home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 2 / Atari Mega Archive CD - Volume 2.iso / linux / src / lnx09p4.dgz / linux-0.9pl4.diffs
Text File  |  1994-11-24  |  430KB  |  14,397 lines

  1. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/MakeVars linux-0.9pl4/MakeVars
  2. --- linux-0.9pl3/MakeVars    Sun Aug 14 10:30:54 1994
  3. +++ linux-0.9pl4/MakeVars    Mon Nov 21 18:08:53 1994
  4. @@ -20,7 +20,7 @@
  5.  ASINCS         = $(INCFLAGS) -O2
  6.  HOSTINCFLAGS     = -Dlinux
  7.  HOSTFLAGS     = -O2 -Wall $(HOSTINCFLAGS)
  8. -LDFLAGS      =
  9. +LDFLAGS      = -qmagic -Ttext 0xC0000FE0
  10.  AR         = ar
  11.  RANLIB         = ranlib
  12.  
  13. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/Makefile linux-0.9pl4/Makefile
  14. --- linux-0.9pl3/Makefile    Tue Sep 27 22:18:26 1994
  15. +++ linux-0.9pl4/Makefile    Mon Nov 21 18:08:53 1994
  16. @@ -1,6 +1,6 @@
  17. -# Makefile for Amiga Linux main source directory
  18. +# Makefile for Linux/68k main source directory
  19.  #
  20. -# Copyright 1993 by Hamish Macdonald
  21. +# Copyright 1993,1994 by Hamish Macdonald
  22.  #
  23.  # This file is subject to the terms and conditions of the GNU General Public
  24.  # License.  See the file "README.legal" in the main directory of this archive
  25. @@ -8,7 +8,7 @@
  26.  
  27.  VERSION = 0
  28.  PATCHLEVEL = 9
  29. -SUBLEVEL = 3
  30. +SUBLEVEL = 4
  31.  
  32.  all:    Version vmlinux
  33.  
  34. @@ -76,13 +76,13 @@
  35.  endif
  36.  
  37.  ifdef CONFIG_AMIGA
  38. -AMIGA_BOOTOBJS := tools/amiga/bootstrap.o tools/amiga/get_nlist.o
  39. +AMIGA_BOOTOBJS := tools/amiga/bootstrap.o
  40.  ARCHIVES := $(ARCHIVES) amiga/amiga.o
  41.  SUBDIRS := $(SUBDIRS) amiga
  42.  endif
  43.  
  44.  ifdef CONFIG_ATARI
  45. -ATARI_BOOTOBJS := tools/atari/bootstrap.o tools/atari/get_nlist.o
  46. +ATARI_BOOTOBJS := tools/atari/bootstrap.o
  47.  ARCHIVES := $(ARCHIVES) atari/atari.o
  48.  SUBDIRS := $(SUBDIRS) atari
  49.  endif
  50. @@ -145,7 +145,7 @@
  51.      $(CC) $(CFLAGS) -c -o $*.o $<
  52.  
  53.  vmlinux: m68k/head.o init/main.o init/config.o tools/version.o linuxsubdirs
  54. -    $(LD) $(LDFLAGS) -T 0xC0000000 -M m68k/head.o init/main.o init/config.o \
  55. +    $(LD) $(LDFLAGS) -M m68k/head.o init/main.o init/config.o \
  56.          tools/version.o \
  57.          $(ARCHIVES) \
  58.          $(FILESYSTEMS) \
  59. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/amiga/amicon.c linux-0.9pl4/amiga/amicon.c
  60. --- linux-0.9pl3/amiga/amicon.c    Sun Aug 14 10:29:40 1994
  61. +++ linux-0.9pl4/amiga/amicon.c    Thu Nov 10 17:56:32 1994
  62. @@ -1079,8 +1079,6 @@
  63.      char *this_opt;
  64.      int i;
  65.      
  66. -    printk ("video_setup: options are %s\n", options);
  67. -    
  68.      if (!options || !*options) {
  69.          return;
  70.      }
  71. @@ -1102,13 +1100,17 @@
  72.      }
  73.      }
  74.  
  75. -static long amicon_init(struct condata *conp, long kmem_start)
  76. +static long amicon_init(struct condata *conp, long kmem_start, char**display_desc)
  77.  {
  78.     int unit = conp - vc_cons;
  79.     register struct display *p = &disp[unit];
  80.     int mode = amicon_mode;
  81.     int inverse_video = amicon_inverse;
  82.     ulong  model;
  83. +   static int master_init = 0;
  84. +
  85. +   if(master_init==0)
  86. +   {
  87.  
  88.     model = boot_info.bi_un.bi_ami.model;
  89.  
  90. @@ -1128,14 +1130,29 @@
  91.         }
  92.         }
  93.  
  94. +      *display_desc = modes[mode].modename;
  95.     init_vblank();
  96. +   
  97.     display_init(p, &modes[mode], inverse_video);
  98. +   }
  99. +   else
  100. +   {
  101. +      /* Copy all from the first console, maybe allow different
  102. +         display modes later. */
  103. +      disp[unit] = disp[0];
  104. +   }
  105.  
  106. -   conp->vc_cols = p->scr_width  / p->fontwidth;
  107. -   conp->vc_rows = p->scr_height / p->fontheight;
  108. +   conp->vc_cols = disp[unit].scr_width / disp[unit].fontwidth;
  109. +   conp->vc_rows = disp[unit].scr_height / disp[unit].fontheight;
  110. +   conp->vc_can_do_color = 0;
  111. +   conp->vc_flags |= CON_INITED;
  112.  
  113. +   if(master_init==0)
  114. +   {
  115.     if(!mach_add_isr(IRQ_AMIGA_VERTB, (isrfunc)amicon_interrupt, 0, NULL))
  116.             panic("Couldn't add vblank interrupt");
  117. +      master_init=1;
  118. +   }
  119.  
  120.  #ifdef DEBUG
  121.     printk("amicon_init: fired up mode %s\n", modes[mode].modename);
  122. @@ -1147,6 +1164,17 @@
  123.  
  124.  static int amicon_deinit (struct condata *conp)
  125.  {
  126. +  struct display *p = &disp[conp - vc_cons];
  127. +  static int amicon_switch (struct condata *conp);
  128. +
  129. +  /* You can't deinit a non inited screen nor the console 0. */
  130. +  if (!(conp->vc_flags & CON_INITED) || p == disp)
  131. +    return -1;
  132. +
  133. +  amicon_switch (&vc_cons[0]);    /* Always switch to the console 0 */
  134. +  memset (p, 0, sizeof (struct display));
  135. +  conp->vc_flags &= ~CON_INITED;
  136. +
  137.      return 0;
  138.  }
  139.  
  140. @@ -1389,9 +1417,11 @@
  141.            int sy, int sx, int dy, int dx,
  142.            int height, int width)
  143.  {
  144. -    int unit = conp - vc_cons;
  145. +    int unit=0;
  146. +/*    int unit = conp - vc_cons;*/
  147.      struct display *p = &disp[unit];
  148.  
  149. +
  150.      if (p->fontwidth == 8) {
  151.          /* Split blits that cross physical y_wrap case.
  152.           * Pathological case involves 4 blits, better to use recursive
  153. @@ -1463,7 +1493,8 @@
  154.  static int amicon_clear (struct condata *conp,
  155.                           int sy, int sx, int height, int width)
  156.  {
  157. -    int unit = conp - vc_cons;
  158. +    int unit = 0;
  159. +    /*int unit = conp - vc_cons;*/
  160.      register struct display *p = &disp[unit];
  161.  
  162.      if (p->fontwidth == 8) {
  163. @@ -1489,7 +1520,7 @@
  164.  }
  165.  
  166.  static void amicon_putc_physical_8 (struct display *p,
  167. -                                    int c, int y, int x, int mode)
  168. +                                    int c, int y, int x, int attr)
  169.  {
  170.      register u_char   *dest;
  171.      register u_char   *cdat;
  172. @@ -1519,14 +1550,10 @@
  173.       */
  174.  
  175.      for (rows = p->fontheight ; rows-- ; dest += bytes)
  176. -    switch (mode) {
  177. -      case DM_COPY:
  178. -        *dest = *cdat++;
  179. -        break;
  180. -      case DM_INVERSE:
  181. +      if (attr & 8)
  182.          *dest = ~*cdat++;
  183. -        break;
  184. -    }
  185. +      else
  186. +    *dest = *cdat++;
  187.  
  188.      for (i = 1 ; i < p->scr_depth ; i++) {
  189.          dest = p->bitplane[i] + offset;
  190. @@ -1535,14 +1562,14 @@
  191.      }
  192.  }
  193.  
  194. -static int amicon_putc (struct condata *conp,
  195. -                        int c, int y, int x, int mode)
  196. +static int amicon_putc (struct condata *conp, int c, int y, int x)
  197.  {
  198. -    int unit = conp - vc_cons;
  199. +    int unit = 0;
  200. +    /*int unit = conp - vc_cons;*/
  201.      register struct display *p = &disp[unit];
  202.  
  203.      if (p->fontwidth == 8) {
  204. -        amicon_putc_physical_8(p, c, real_y_8(p, y) , x, mode);
  205. +        amicon_putc_physical_8(p, c, real_y_8(p, y) , x, conp->vc_attr);
  206.      } else {
  207.          /* Currently no support for (fontwidth != 8) */
  208.      }
  209. @@ -1551,7 +1578,7 @@
  210.  }
  211.  
  212.  static void amicon_putcs_physical_8 (struct display *p, const char *s,
  213. -                                     int count, int y, int x, int mode)
  214. +                                     int count, int y, int x, int attr)
  215.  {
  216.      register u_char   *dest, *cdat;
  217.      register ushort   rows, bytes;
  218. @@ -1586,8 +1613,7 @@
  219.           * d0 -- scratch  ; d1 -- count  ; d2 -- bytes
  220.           * 
  221.           */
  222. -    switch (mode) {
  223. -      case DM_COPY:
  224. +    if (!(attr & 0x8))
  225.          __asm__("movel  %1,d1   ; beq 5f      ; subqw #1,d1\n\t"
  226.              "movel  %0,a0   ; movel %2,a2\n\t"
  227.              "movel %3,a3;movel %4,d2\n\t"
  228. @@ -1611,8 +1637,7 @@
  229.              : "g" (dest0), "g" (count), "g" (s),
  230.              "g" (p->fontdata), "g" ((ulong) bytes)
  231.              : "a0", "a1", "a2", "a3", "d0", "d1", "d2");
  232. -        break;
  233. -      case DM_INVERSE:
  234. +    else
  235.          __asm__("movel  %1,d1   ; beq 5f      ; subqw #1,d1\n\t"
  236.              "movel  %0,a0   ; movel %2,a2\n\t"
  237.              "movel %3,a3;movel %4,d2\n\t"
  238. @@ -1636,8 +1661,6 @@
  239.              : "g" (dest0), "g" (count), "g" (s),
  240.              "g" (p->fontdata), "g" ((ulong) bytes)
  241.              : "a0", "a1", "a2", "a3", "d0", "d1", "d2", "d3");
  242. -        break;
  243. -    }
  244.      return;
  245.      }
  246.  #endif
  247. @@ -1663,25 +1686,22 @@
  248.  
  249.          cdat  = p->fontdata + (c * p->fontheight);
  250.          for (rows = p->fontheight ; rows-- ; dest += bytes)
  251. -        switch (mode) {
  252. -          case DM_COPY:
  253. +      if (!(attr & 8))
  254.          *dest = *cdat++;
  255. -        break;
  256. -          case DM_INVERSE:
  257. +      else
  258.          *dest = ~*cdat++;
  259. -        break;
  260. -        }
  261.      }
  262.  }
  263.  
  264.  static int amicon_putcs (struct condata *conp, const char *s,
  265. -                         int count, int y, int x, int mode)
  266. +                         int count, int y, int x)
  267.  {
  268. -    int unit = conp - vc_cons;
  269. +    int unit = 0;
  270. +    /*int unit = conp - vc_cons;*/
  271.      register struct display *p = &disp[unit];
  272.  
  273.      if (p->fontwidth == 8) {
  274. -        amicon_putcs_physical_8(p, s, count, real_y_8(p, y) , x, mode);
  275. +        amicon_putcs_physical_8(p, s, count, real_y_8(p, y) , x, conp->vc_attr);
  276.      } else {
  277.          /* Currently no support for (fontwidth != 8) */
  278.      }
  279. @@ -1692,7 +1712,8 @@
  280.  static int amicon_cursor (struct condata *conp,
  281.             int mode)
  282.  {
  283. -   int unit = conp - vc_cons;
  284. +   int unit=0;
  285. +   /*int unit = conp - vc_cons;*/
  286.     struct display *p = &disp[unit];
  287.  
  288.     if (mode == CM_ERASE) {
  289. @@ -1710,7 +1731,8 @@
  290.  static int amicon_scroll (struct condata *conp,
  291.                            int t, int b, int dir, int count)
  292.  {
  293. -    int unit                   = conp - vc_cons;
  294. +    int unit=0;
  295. +    /*int unit                   = conp - vc_cons;*/
  296.      register struct display *p = &disp[unit];
  297.  
  298.      amicon_cursor (conp, CM_ERASE);
  299. @@ -1773,6 +1795,21 @@
  300.  
  301.  static int amicon_switch (struct condata *conp)
  302.  {
  303. +  struct display *p = &disp[conp - vc_cons];
  304. +  struct display *old = &disp[fg_console];
  305. +
  306. +  if (!(conp->vc_flags & CON_INITED))
  307. +    return -1;
  308. +
  309. +  p->bitplane[0] = old->bitplane[0];    /* syncing the base address */
  310. +  p->bitplane[1] = old->bitplane[1];    /* syncing the base address */
  311. +  p->bitplane[2] = old->bitplane[2];    /* syncing the base address */
  312. +  p->bitplane[3] = old->bitplane[3];    /* syncing the base address */
  313. +  p->bitplane[4] = old->bitplane[4];    /* syncing the base address */
  314. +  p->bitplane[5] = old->bitplane[5];    /* syncing the base address */
  315. +  p->bitplane[6] = old->bitplane[6];    /* syncing the base address */
  316. +  p->bitplane[7] = old->bitplane[7];    /* syncing the base address */
  317. +
  318.      return 0;
  319.  }
  320.  
  321. @@ -1796,4 +1833,3 @@
  322.      amicon_init, amicon_deinit, amicon_clear, amicon_putc, amicon_putcs,
  323.      amicon_cursor, amicon_scroll, amicon_bmove, amicon_switch, amicon_blank
  324.  };
  325. -
  326. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/amiga/config.c linux-0.9pl4/amiga/config.c
  327. --- linux-0.9pl3/amiga/config.c    Sun Aug 14 10:29:40 1994
  328. +++ linux-0.9pl4/amiga/config.c    Sat Nov 12 09:16:52 1994
  329. @@ -66,25 +66,33 @@
  330.      lo    = ciab.talo;
  331.      hi2 = ciab.tahi;
  332.  
  333. -    if (hi != hi2)
  334. +    if (hi != hi2) {
  335.      lo = ciab.talo;
  336. +    hi = hi2;
  337. +    }
  338.  
  339.      ticks = hi << 8 | lo;
  340.  
  341.      if (boot_info.bi_amiga.eclock == NTSC_ECLOCK) {
  342. +#if 0 /* XXX */
  343. +/* reading the ICR clears all interrupts.  bad idea! */
  344.      if (ticks > NTSC_JIFFY_TICKS - NTSC_JIFFY_TICKS / 100)
  345.        /* check for pending interrupt */
  346.        if (ciab.icr & CIA_ICR_TA)
  347.          offset = 10000;
  348. +#endif
  349.      ticks = (NTSC_JIFFY_TICKS-1) - ticks;
  350. -    ticks = 10000 * ticks / NTSC_JIFFY_TICKS;
  351. +    ticks = (10000 * ticks) / NTSC_JIFFY_TICKS;
  352.      } else {
  353. +#if 0 /* XXX */
  354. +/* reading the ICR clears all interrupts.  bad idea! */
  355.      if (ticks > PAL_JIFFY_TICKS - PAL_JIFFY_TICKS / 100)
  356.        /* check for pending interrupt */
  357.        if (ciab.icr & CIA_ICR_TA)
  358.          offset = 10000;
  359. +#endif
  360.      ticks = (PAL_JIFFY_TICKS-1) - ticks;
  361. -    ticks = 10000 * ticks / NTSC_JIFFY_TICKS;
  362. +    ticks = (10000 * ticks) / NTSC_JIFFY_TICKS;
  363.      }
  364.  
  365.      return ticks + offset;
  366. @@ -194,21 +202,27 @@
  367.  
  368.  void amiga_reset (void)
  369.  {
  370. +  unsigned long jmp_addr040 = VTOP(&&jmp_addr_label040);
  371.      unsigned long jmp_addr = VTOP(&&jmp_addr_label);
  372.  
  373.      cli();
  374.      if (boot_info.cputype & CPU_68040)
  375. +    /* Setup transparent translation registers for mapping
  376. +     * of 16 MB kernel segment before disabling translation
  377. +     */
  378.      __asm__ __volatile__
  379. -        ("moveq #0,d0\n\t"
  380. -         "bra   2f\n\t"
  381. -         ".align 4\n\t"        /* align on cache line start */
  382. -         "2:\n\t"
  383. -         ".long 0x4e7b0003\n\t"    /* movec d0,tc */
  384. +      ("movel    %0,d0\n\t"
  385. +       "andl     #0xff000000,d0\n\t"
  386. +       "orw      #0xe020,d0\n\t"   /* map 16 MB, enable, cacheable */
  387. +       ".long    0x4e7b0004\n\t"   /* movec d0,itt0 */
  388. +       ".long    0x4e7b0006\n\t"   /* movec d0,dtt0 */
  389.           "jmp   %0@\n\t"
  390.           : /* no outputs */
  391. -         : "a" (jmp_addr)
  392. -         : "d0");
  393. +       : "a" (jmp_addr040));
  394.      else
  395. +    /* for 680[23]0, just disable translation and jump to the physical
  396. +     * address of the label
  397. +     */
  398.      __asm__ __volatile__
  399.          ("pmove  tc,sp@\n\t"
  400.           "bclr   #7,sp@\n\t"
  401. @@ -216,10 +230,21 @@
  402.           "jmp    %0@\n\t"
  403.           : /* no outputs */
  404.           : "a" (jmp_addr));
  405. + jmp_addr_label040:
  406. +  /* disable translation on '040 now */
  407. +  __asm__ __volatile__    
  408. +    ("moveq #0,d0\n\t"
  409. +     ".long 0x4e7b0003\n\t"         /* movec d0,tc; disable MMU */
  410. +     : /* no outputs */
  411. +     : /* no inputs */
  412. +     : "d0");
  413. +
  414.    jmp_addr_label:
  415. +  /* pickup reset address from AmigaOS ROM, reset devices and jump
  416. +   * to reset address
  417. +   */
  418.      __asm__ __volatile__
  419. -    ("movew #0x2700,sr\n\t"
  420. -     "leal  0x01000000,a0\n\t"
  421. +    ("leal  0x01000000,a0\n\t"
  422.       "subl  a0@(-0x14),a0\n\t"
  423.       "movel a0@(4),a0\n\t"
  424.       "subql #2,a0\n\t"
  425. @@ -231,4 +256,5 @@
  426.       "jmp   a0@");
  427.  
  428.      for (;;);
  429. +
  430.  }
  431. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/atari/atacon.c linux-0.9pl4/atari/atacon.c
  432. --- linux-0.9pl3/atari/atacon.c    Tue Sep 27 22:19:35 1994
  433. +++ linux-0.9pl4/atari/atacon.c    Mon Nov 21 18:08:54 1994
  434. @@ -37,14 +37,22 @@
  435.  #define    CONFIG_ATARI_8PLANE
  436.  #undef    CONFIG_ATARI_16PLANE
  437.  
  438. +/* If you do not work with X Windows, hardware scrolling may be
  439. + * nice...
  440. + */
  441. +#define HARDWARE_SCROLLING
  442. +
  443. +/* If you want to see underlined characters in color modes, define the
  444. + * following flag. But note that this effect cannot be restored when
  445. + * switching VC's!
  446. + */
  447. +#undef COLOR_UNDERLINING
  448. +
  449.  /* To do:
  450.   *
  451.   *  - Do proper Falcon video mode setting, analogous to the TT (but
  452.   *    much more and better modes possible!)
  453.   *  - Implement 16 plane mode.
  454. - *  - Do a backing store of characters and attributes on the screen
  455. - *    for conole switching (or will this be done in the device
  456. - *    independent part (console.c) ?)
  457.   *
  458.   */
  459.  
  460. @@ -76,7 +84,16 @@
  461.      fontname_8x16[], fontname_8x8[];
  462.  
  463.  
  464. +/* Import console_blanked from console.c */
  465. +
  466. +extern int console_blanked;
  467.  
  468. +/* This macro should return true, if in this mode the
  469. + * blanking/unblanking is done by blackening and redrawing the screen
  470. + */
  471. +#define REDRAW_BLANK_MODE(cons)                    \
  472. +    (boot_info.bi_atari.model == ATARI_TT &&    \
  473. +     disp[(cons)].shiftmode == TT_HIGH)
  474.  
  475.  
  476.  /* FONT_CNV does the character conversion necessary if the font
  477. @@ -93,25 +110,16 @@
  478.   *                                                             Roman
  479.   */
  480.  
  481. +/* ++andreas: Translation now done in console.c */
  482. +
  483.  #ifndef WHOLE_FONT
  484.  
  485. -#define    FONT_CNV(c) ({
  486. -   int __rv = 1;
  487. -   if ((c >= 32) && (c < 127))
  488. -       /* lower half of charset -- normal ASCII */
  489. -       c -=  32;
  490. -    else if ((c >= 160) && (c < 255))
  491. -        /* upper half of charset -- special characters */
  492. -        c -= 64;
  493. -    else
  494. -        /* not defined in charset -- non-printable character */
  495. -        __rv = 0;
  496. -   __rv;
  497. -})
  498. +#define    FONT_CNV(c) (((c) -= 32) >= 0 \
  499. +             && ((c) <= 127 - 32 || ((c) -= 32) >= 160 - 64))
  500.  
  501.  #else
  502.  
  503. -#define    FONT_CNV(c) ((c = conp->vc_translate[c]) != 0)
  504. +#define    FONT_CNV(c) (1)
  505.  
  506.  #endif
  507.  
  508. @@ -140,9 +148,9 @@
  509.      void (*clear)( struct condata *conp, register struct display *p,
  510.                     int sy, int sx, int height, int width);
  511.      void (*putc)( struct condata *conp, struct display *p, int c,
  512. -                  int y, int x, int mode );
  513. +                  int y, int x);
  514.      void (*putcs)( struct condata *conp, struct display *p,
  515. -                   const char *s, int count, int y, int x, int mode);
  516. +                   const char *s, int count, int y, int x);
  517.      void (*rev_char)( struct display *display, int x, int y );
  518.  };    
  519.  
  520. @@ -165,9 +173,11 @@
  521.      u_char *bitplane;            /* pointer to display bitmap; planes
  522.                                   * are interleaved!
  523.                                   */
  524. +#ifdef HARDWARE_SCROLLING
  525.      u_char *screen_base;    /* Base of display bitmap for hardware
  526.                     scrolling */
  527.      u_char *screen_end;        /* End of first half of display bitmap */
  528. +#endif
  529.  
  530.      u_long *color_map;          /* XXX Not yet implemented XXX */
  531.  
  532. @@ -193,10 +203,13 @@
  533.      { "ttlow",   320 , 480 , 8 } };            /* TT-Low */
  534.      
  535.  static struct tt_vid_type falcon_video_modes[] = {
  536. +    { "sthigh",    640 , 400 , 1 } ,        /* ST-High */
  537.      { "vga16",   640 , 480 , 4 } ,            /* VGA 16 colors */
  538.      { "vga4",    640 , 480 , 2 } ,            /* VGA 4 colors */
  539.      { "vga2",    640 , 480 , 1 } ,            /* VGA 2 colors */
  540. -    { "vga256",  640 , 480 , 8 }             /* VGA 256 colors */
  541. +    { "vga256",  640 , 480 , 8 } ,            /* VGA 256 colors */
  542. +    { "falh2",   896 , 608 , 1 } ,            /* hires for sblaster */
  543. +    { "falh16",  896 , 608 , 4 }             /* hires for sblaster */
  544.  };
  545.  
  546.  /* Default color maps for 4 and 2 plane modes. These use the PC-ish
  547. @@ -291,7 +304,7 @@
  548.  
  549.  static void detect_video (int *yres, int *xres, int *depth, int *shiftmode);
  550.  static int shifter_init( u_long adr);
  551. -static long atacon_init( struct condata *conp, long mem_start);
  552. +static long atacon_init( struct condata *conp, long mem_start, char **display_desc);
  553.  static int atacon_deinit( struct condata *conp);
  554.  static __inline__ void *mymemclear_small( void * s, size_t count);
  555.  static __inline__ void *mymemclear( void * s, size_t count);
  556. @@ -323,10 +336,9 @@
  557.                           dx, int height, int width);
  558.  static int atacon_clear( struct condata *conp, int sy, int sx, int height,
  559.                           int width);
  560. -static int atacon_putc( struct condata *conp, int c, int y, int x, int
  561. -                        mode);
  562. +static int atacon_putc( struct condata *conp, int c, int y, int x);
  563.  static int atacon_putcs( struct condata *conp, const char *s, int count,
  564. -                         int y, int x, int mode);
  565. +                         int y, int x);
  566.  static int atacon_scroll( struct condata *conp, int t, int b, int dir, int
  567.                            count);
  568.  static int atacon_switch( struct condata *conp);
  569. @@ -337,12 +349,10 @@
  570.                                    display *p, int sy, int sx, int height,
  571.                                    int width );
  572.  static void atacon_putc_1_plane( struct condata *conp, struct display *p,
  573. -                                 int c, int y, int x, int mode);
  574. +                                 int c, int y, int x);
  575.  static void atacon_putcs_1_plane( struct condata *conp, struct display *p,
  576. -                                  const char *s, int count, int y, int x,
  577. -                                  int mode);
  578. -static void atacon_rev_char_1_plane( struct display *display, int x, int y
  579. -                                     );
  580. +                                  const char *s, int count, int y, int x);
  581. +static void atacon_rev_char_1_plane( struct display *display, int x, int y );
  582.  #ifdef CONFIG_ATARI_2PLANE
  583.  static void atacon_bmove_2_plane( register struct display *p, int sy, int
  584.                                    sx, int dy, int dx, int height, int
  585. @@ -351,12 +361,10 @@
  586.                                    display *p, int sy, int sx, int height,
  587.                                    int width );
  588.  static void atacon_putc_2_plane( struct condata *conp, struct display *p,
  589. -                                 int c, int y, int x, int mode);
  590. +                                 int c, int y, int x);
  591.  static void atacon_putcs_2_plane( struct condata *conp, struct display *p,
  592. -                                  const char *s, int count, int y, int x,
  593. -                                  int mode);
  594. -static void atacon_rev_char_2_plane( struct display *display, int x, int y
  595. -                                     );
  596. +                                  const char *s, int count, int y, int x);
  597. +static void atacon_rev_char_2_plane( struct display *display, int x, int y );
  598.  #endif
  599.  #ifdef CONFIG_ATARI_4PLANE
  600.  static void atacon_bmove_4_plane( register struct display *p, int sy, int
  601. @@ -366,12 +374,10 @@
  602.                                    display *p, int sy, int sx, int height,
  603.                                    int width );
  604.  static void atacon_putc_4_plane( struct condata *conp, struct display *p,
  605. -                                 int c, int y, int x, int mode);
  606. +                                 int c, int y, int x);
  607.  static void atacon_putcs_4_plane( struct condata *conp, struct display *p,
  608. -                                  const char *s, int count, int y, int x,
  609. -                                  int mode);
  610. -static void atacon_rev_char_4_plane( struct display *display, int x, int y
  611. -                                     );
  612. +                                  const char *s, int count, int y, int x);
  613. +static void atacon_rev_char_4_plane( struct display *display, int x, int y );
  614.  #endif
  615.  #ifdef CONFIG_ATARI_8PLANE
  616.  static void atacon_bmove_8_plane( register struct display *p, int sy, int
  617. @@ -381,12 +387,10 @@
  618.                                    display *p, int sy, int sx, int height,
  619.                                    int width );
  620.  static void atacon_putc_8_plane( struct condata *conp, struct display *p,
  621. -                                 int c, int y, int x, int mode);
  622. +                                 int c, int y, int x);
  623.  static void atacon_putcs_8_plane( struct condata *conp, struct display *p,
  624. -                                  const char *s, int count, int y, int x,
  625. -                                  int mode);
  626. -static void atacon_rev_char_8_plane( struct display *display, int x, int y
  627. -                                     );
  628. +                                  const char *s, int count, int y, int x);
  629. +static void atacon_rev_char_8_plane( struct display *display, int x, int y );
  630.  #endif
  631.  #ifdef CURSOR_DELAY_TIMER
  632.  static void atacon_curtimfunc( unsigned long _disp );
  633. @@ -601,8 +605,9 @@
  634.      }
  635.   }
  636.  
  637. -static int shifter_init(u_long adr)
  638. +static int shifter_init(u_long vadr)
  639.   {
  640. +  u_long adr = VTOP(vadr);
  641.  /* Setup Screen Memory */
  642.    shifter.bas_hi=(u_char)((adr & 0xff0000) >> 16);
  643.    shifter.bas_md=(u_char)((adr & 0x00ff00) >> 8);
  644. @@ -611,12 +616,16 @@
  645.   }
  646.  
  647.  
  648. -static long atacon_init(struct condata *conp, long mem_start)
  649. +static long atacon_init(struct condata *conp, long mem_start, char **display_desc)
  650.  {
  651.      int unit = conp - vc_cons;    
  652.      unsigned long mem_req;
  653.      u_char *screen_base;
  654. +    static int master_init = 0;
  655. +    static char mode_name[40];
  656.  
  657. +    if (!master_init) {
  658. +        master_init = 1;
  659.      /* set up the display defaults */
  660.      detect_video( &disp[unit].scr_height, &disp[unit].scr_width,
  661.                    &disp[unit].scr_depth, &disp[unit].shiftmode );
  662. @@ -684,31 +693,76 @@
  663.          panic( "atacon_init: %d planes not supported.\n",
  664.                 disp[unit].scr_depth );
  665.      
  666. -    conp->vc_cols = disp[unit].scr_width / disp[unit].fontwidth;
  667. -    conp->vc_rows = disp[unit].scr_height / disp[unit].fontheight;
  668.  
  669. +#ifdef HARDWARE_SCROLLING
  670. +        /* For hardware scrolling, allocate twice the memory we'd need for
  671. +         * one screen.
  672. +         * The base is rounded up to the next multiple of 8.
  673. +         */
  674.      mem_req = (disp[unit].scr_width/8)*disp[unit].scr_height*
  675.                disp[unit].scr_depth;
  676. -    /* locate the bitplane */
  677. -    /* GK: why allocate 2*mem_req ???? */
  678. -    screen_base = atari_stram_alloc (mem_req * 2 + 8);
  679. +        screen_base = atari_stram_alloc (mem_req * 2 + 8, &mem_start );
  680.      screen_base = (u_char *) (((u_long) screen_base + 7) & ~7);
  681. -    disp[unit].screen_base = disp[unit].bitplane = screen_base;
  682. +        disp[unit].screen_base = screen_base;
  683.      disp[unit].screen_end = screen_base + mem_req;
  684. +#else
  685. +        /* If hardware scrolling is disabled, but support for X should
  686. +         * come up, allocate the screen mem page-aligned... (begin and end!)
  687. +         */
  688. +        mem_req = (disp[unit].scr_width/8)*disp[unit].scr_height*
  689. +            disp[unit].scr_depth;
  690. +        mem_req = ((mem_req + PAGE_SIZE - 1) & PAGE_MASK) + PAGE_SIZE;
  691. +        screen_base = atari_stram_alloc( mem_req, &mem_start );
  692. +        screen_base = (u_char *) (((u_long)screen_base + PAGE_SIZE - 1) & PAGE_MASK);
  693. +#endif
  694. +        disp[unit].bitplane = screen_base;
  695.      memset (screen_base, 0, mem_req);
  696.  
  697.      shifter_init ((unsigned long)screen_base);
  698.      
  699. +        switch( boot_info.bi_atari.model ) {
  700. +              case ATARI_TT:
  701. +            strcpy( mode_name, "TT native " );
  702. +            strcat( mode_name, tt_video_modes[disp[unit].shiftmode].name );
  703. +            break;
  704. +              case ATARI_FALCON:
  705. +            strcpy( mode_name, "Falcon native " );
  706. +            strcat( mode_name, falcon_video_modes[disp[unit].shiftmode].name );
  707. +            break;
  708. +              default:
  709. +            strcpy( mode_name, "unknown Atari graphics" );
  710. +            break;
  711. +        }
  712. +        *display_desc = mode_name;
  713.  
  714.  #ifdef CURSOR_DELAY_VBL
  715.      add_isr( IRQ4, atacon_vbl_handler, 0, NULL );
  716.  #endif
  717. +    }
  718. +    else
  719. +        /* Copy all from the first console, maybe allow different
  720. +           display modes later. */
  721. +        disp[unit] = disp[0];
  722. +    
  723. +    conp->vc_cols = disp[unit].scr_width / disp[unit].fontwidth;
  724. +    conp->vc_rows = disp[unit].scr_height / disp[unit].fontheight;
  725. +    conp->vc_flags |= CON_INITED;
  726. +    conp->vc_can_do_color = disp[unit].scr_depth != 1;
  727.      
  728.      return mem_start;
  729.  }
  730.  
  731.  static int atacon_deinit (struct condata *conp)
  732.  {
  733. +  struct display *p = &disp[conp - vc_cons];
  734. +
  735. +  /* You can't deinit a non inited screen nor the console 0. */
  736. +  if (!(conp->vc_flags & CON_INITED) || p == disp)
  737. +    return -1;
  738. +
  739. +  atacon_switch (&vc_cons[0]);    /* Always switch to the console 0 */
  740. +  memset (p, 0, sizeof (struct display));
  741. +  conp->vc_flags &= ~CON_INITED;
  742.      return 0;
  743.  }
  744.  
  745. @@ -821,6 +875,28 @@
  746.      return(0);              
  747.  }
  748.  
  749. +static __inline__ void *mymemset(void * s, size_t count)
  750. +
  751. +{
  752. +  if (!count) return(0);
  753. +  
  754. +  __asm__ __volatile__
  755. +    ("lsrl   #1,%1 ; jcc 1f ; moveb %2,%0@-\n\t"
  756. +     "1: lsrl   #1,%1 ; jcc 1f ; movew %2,%0@-\n\t"
  757. +     "1: lsrl   #1,%1 ; jcc 1f ; movel %2,%0@-\n\t"
  758. +     "1: lsrl   #1,%1 ; jcc 1f ; movel %2,%0@- ; movel %2,%0@-\n\t"
  759. +     "1: subql  #1,%1 ; jcs 3f\n\t"
  760. +     "2: moveml %2/%3/%4/%5,%0@-\n\t"
  761. +     "dbra %1,2b\n\t"
  762. +     "3:"
  763. +     : "=a" (s), "=d" (count)
  764. +     :  "d" (-1), "d" (-1), "d" (-1), "d" (-1),
  765. +     "0" ((char *) s + count), "1" (count)
  766. +     );
  767. +  
  768. +  return(0);              
  769. +}
  770. +
  771.  static __inline__ void *mymemmove(void * d, void * s, size_t count)
  772.  {
  773.      if (d < s) {
  774. @@ -1384,6 +1460,9 @@
  775.      int unit = conp - vc_cons;
  776.      struct display *p = &disp[unit];
  777.      
  778. +    if (REDRAW_BLANK_MODE(unit) && console_blanked)
  779. +        return( 0 );
  780. +    
  781.      if ((sy <= p->cursor_y && p->cursor_y < sy+height &&
  782.           sx <= p->cursor_x && p->cursor_x < sx+width)   ||
  783.          (dy <= p->cursor_y && p->cursor_y < dy+height &&
  784. @@ -1400,6 +1479,9 @@
  785.      int unit = conp - vc_cons;
  786.      register struct display *p = &disp[unit];
  787.  
  788. +    if (REDRAW_BLANK_MODE(unit) && console_blanked)
  789. +        return( 0 );
  790. +    
  791.      if (sy <= p->cursor_y && p->cursor_y < sy+height &&
  792.          sx <= p->cursor_x && p->cursor_x < sx+width)
  793.          CURSOR_UNDRAWN();
  794. @@ -1409,31 +1491,36 @@
  795.      return(0);
  796.  }
  797.  
  798. -static int atacon_putc (struct condata *conp,
  799. -                        int c, int y, int x, int mode)
  800. +static int atacon_putc (struct condata *conp, int c, int y, int x)
  801.  {
  802.      int unit = conp - vc_cons;
  803.      register struct display *p = &disp[unit];
  804.  
  805. +    if (REDRAW_BLANK_MODE(unit) && console_blanked)
  806. +        return( 0 );
  807. +    
  808.      if (p->cursor_x == x && p->cursor_y == y)
  809.          CURSOR_UNDRAWN();
  810.      
  811. -    p->dispsw->putc( conp, p, c, y, x, mode );
  812. +    p->dispsw->putc( conp, p, c, y, x );
  813.  
  814.      return(0);
  815.  }
  816.  
  817.  static int atacon_putcs (struct condata *conp, const char *s,
  818. -                         int count, int y, int x, int mode)
  819. +                         int count, int y, int x)
  820.  {
  821.      int unit = conp - vc_cons;
  822.      register struct display *p = &disp[unit];
  823.  
  824. +    if (REDRAW_BLANK_MODE(unit) && console_blanked)
  825. +        return( 0 );
  826. +    
  827.      if (p->cursor_y == y &&
  828.          x <= p->cursor_x && p->cursor_x < x+count)
  829.          CURSOR_UNDRAWN();
  830.      
  831. -    p->dispsw->putcs( conp, p, s, count, y, x, mode );
  832. +    p->dispsw->putcs( conp, p, s, count, y, x );
  833.  
  834.      return(0);
  835.  }
  836. @@ -1442,9 +1529,13 @@
  837.  static int atacon_scroll (struct condata *conp,
  838.                            int t, int b, int dir, int count)
  839.  {
  840. +    if (REDRAW_BLANK_MODE(conp-vc_cons) && console_blanked)
  841. +        return( 0 );
  842. +    
  843.      switch (dir) {
  844.  
  845.      case SM_UP:
  846. +#ifdef HARDWARE_SCROLLING
  847.        /* Use hardware scrolling if possible */
  848.        if (t == 0 && b == conp->vc_rows)
  849.      {
  850. @@ -1464,12 +1555,14 @@
  851.        shifter_init ((u_long) p->bitplane);
  852.      }
  853.        else
  854. +#endif
  855.          atacon_bmove( conp, t + count, 0, t, 0,
  856.                        (b-t-count), conp->vc_cols );
  857.          atacon_clear( conp, b-count, 0, count, conp->vc_cols );
  858.          break;
  859.  
  860.      case SM_DOWN:
  861. +#ifdef HARDWARE_SCROLLING
  862.        /* Use hardware scrolling if possible */
  863.        if (t == 0 && b == conp->vc_rows)
  864.      {
  865. @@ -1490,6 +1583,7 @@
  866.        shifter_init ((u_long) p->bitplane);
  867.      }
  868.        else
  869. +#endif
  870.          atacon_bmove( conp, t, 0, t+count, 0,
  871.                        (b-t-count), conp->vc_cols );
  872.  
  873. @@ -1519,11 +1613,61 @@
  874.  
  875.  static int atacon_switch (struct condata *conp)
  876.  {
  877. +#ifdef HARDWARE_SCROLLING
  878. +  struct display *p = &disp[conp - vc_cons];
  879. +  struct display *old = &disp[fg_console];
  880. +#endif
  881. +
  882. +  if (!(conp->vc_flags & CON_INITED))
  883. +    return -1;
  884. +
  885. +#ifdef HARDWARE_SCROLLING
  886. +  p->bitplane = old->bitplane;    /* syncing the base address */
  887. +#endif
  888.      return 0;
  889.  }
  890.  
  891.  static int atacon_blank (int blank)
  892.  {
  893. +  static u_short saved_tt_palette[256];
  894. +  int i;
  895. +
  896. +  if (boot_info.bi_atari.model != ATARI_TT)
  897. +    return 0;
  898. +
  899. +  atacon_cursor( &vc_cons[fg_console], blank ? CM_ERASE : CM_DRAW );
  900. +  
  901. +  if (REDRAW_BLANK_MODE(fg_console)) {
  902. +    /* Special treatment for TT High mode: Changing the palette
  903. +     * registers isn't possible, so the screen is filled with black
  904. +     * for blanking and completely restored for unblanking.
  905. +     */
  906. +    if (blank) {
  907. +        struct display *p = &disp[fg_console];
  908. +        mymemset( p->bitplane, p->bytes_per_row * p->scr_height );
  909. +        return( 0 );
  910. +    }
  911. +    else {
  912. +        /* Tell console.c that it has to completely restore the
  913. +         * screen itself
  914. +         */
  915. +        return( 1 );
  916. +    }
  917. +  }
  918. +
  919. +  if (blank)
  920. +    {
  921. +      for (i = 0; i < 256; i++)
  922. +    {
  923. +      saved_tt_palette[i] = tt_palette[i];
  924. +      tt_palette[i] = 0;
  925. +    }
  926. +    }
  927. +  else
  928. +    {
  929. +      for (i = 0; i < 256; i++)
  930. +    tt_palette[i] = saved_tt_palette[i];
  931. +    }
  932.      return 0;
  933.  }
  934.  
  935. @@ -1596,8 +1740,29 @@
  936.  }
  937.  
  938.  
  939. +/* The text effects (bold, reverse, light, underlined, blink) are represented
  940. + * in the attribute byte as follows: (like a monochrome PC graphics adapter):
  941. + * 
  942. + *  - (attr & 0x80) == 0x00 =>  not blinking
  943. + *                  == 0x80 =>  blinking (not implemented, ignored)
  944. + *  - (attr & 0x70) != 0    =>  reverse
  945. + *                  == 0    =>  not reverse
  946. + *  - (attr & 0x03) == 0x01 =>  underlined
  947. + *                  != 0x01 =>  not underlined
  948. + *  - (attr & 0x08) == 0    =>  normal intensity
  949. + *    (attr & 0x08) != 0 && (attr & 0x77) == 0 => light (half intensity)
  950. + *                                        != 0 => bright (bold, double intensity)
  951. + *
  952. + * Note that several combinations of effects are not possible with
  953. + * that representation. Light mode isn't possible if underlined and/or
  954. + * reverse mode are active. Characters are printed bright in that
  955. + * cases instead of light :-( Maybe the representation should be
  956. + * changed (separate bits for each effect)...
  957. + *
  958. + */
  959. +
  960.  static void atacon_putc_1_plane( struct condata *conp, struct display *p,
  961. -                                 int c, int y, int x, int mode)
  962. +                                 int c, int y, int x)
  963.  {
  964.      register u_char   *dest;
  965.      register u_char   *cdat;
  966. @@ -1613,28 +1778,27 @@
  967.      dest  = p->bitplane + offset;
  968.      cdat  = p->fontdata + (c * p->fontheight);
  969.  
  970. -    if (conp->vc_intensity != 1 || conp->vc_reverse ^ conp->vc_decscnm) {
  971. +    if ((conp->vc_attr & 0x0b) != 0x01) {
  972.          register u_char    andmask, xormask, c;
  973.          register int    bold;
  974.          
  975. -        andmask = (conp->vc_intensity == 0) ? 0x55 : 0xff;
  976. -        xormask = (conp->vc_reverse ^ conp->vc_decscnm) ? 0xff : 0;
  977. -        bold = (conp->vc_intensity == 2);
  978. +      xormask = (conp->vc_attr & 0x08) ? 0xff : 0;           /* reverse */
  979. +      andmask = ((conp->vc_attr & 0x03) == 0) ? 0x55 : 0xff; /* light */
  980. +      bold    = ((conp->vc_attr & 0x03) == 2);               /* bold/bright */
  981.          
  982.          for (rows = p->fontheight ; rows-- ; dest += bytes) {
  983.              c = *cdat++;
  984. -            if (rows == 0 && conp->vc_underline) c = 0xff;
  985. +    if (rows == 0 && (conp->vc_attr & 0x04)) c = 0xff;
  986.              c = (c & andmask) ^ xormask;
  987.              if (bold) c |= c >> 1;
  988.              *dest = c;
  989.          }
  990.      }
  991.      else {
  992. -        
  993.          for (rows = p->fontheight ; rows-- ; dest += bytes)
  994.              *dest = *cdat++;
  995.  
  996. -        if (conp->vc_underline)
  997. +      if (conp->vc_attr & 0x04) /* underlined */
  998.              dest[-bytes] ^= ~0;
  999.      }
  1000.  }
  1001. @@ -1642,15 +1806,14 @@
  1002.  
  1003.  static void atacon_putcs_1_plane( struct condata *conp, struct
  1004.                                    display *p, const char *s,
  1005. -                                  int count, int y, int x, int mode)
  1006. +                                  int count, int y, int x)
  1007.  {
  1008.      register u_char   *dest, *cdat;
  1009.      register int rows, bytes;
  1010.      register u_char   c;
  1011.      u_char   *dest0;
  1012.      ulong    offset;
  1013. -    int         effects = (conp->vc_underline || conp->vc_intensity != 1 ||
  1014. -                        (conp->vc_reverse ^ conp->vc_decscnm));
  1015. +    int      effects = (conp->vc_attr & 0x0f) != 0x01;
  1016.      
  1017.      if (!count) return;
  1018.      
  1019. @@ -1721,9 +1884,9 @@
  1020.          register u_char    andmask, xormask, ch;
  1021.          register int    bold;
  1022.          
  1023. -        andmask = (conp->vc_intensity == 0) ? 0x55 : 0xff;
  1024. -        xormask = (conp->vc_reverse ^ conp->vc_decscnm) ? 0xff : 0;
  1025. -        bold = (conp->vc_intensity == 2);
  1026. +        xormask = (conp->vc_attr & 0x08) ? 0xff : 0;
  1027. +        andmask = ((conp->vc_attr & 0x03) == 0) ? 0x55 : 0xff;
  1028. +        bold = ((conp->vc_attr & 0x03) == 2);
  1029.  
  1030.          while (count--) {
  1031.              c = *(s++);
  1032. @@ -1734,7 +1897,7 @@
  1033.  
  1034.              for (rows = p->fontheight ; rows-- ; dest += bytes) {
  1035.                  ch = *cdat++;
  1036. -                if (rows == 0 && conp->vc_underline) ch = 0xff;
  1037. +                if (rows == 0 && (conp->vc_attr & 0x04)) ch = 0xff;
  1038.                  ch = (ch & andmask) ^ xormask;
  1039.                  if (bold) ch |= ch >> 1;
  1040.                  *dest = ch;
  1041. @@ -1972,7 +2135,7 @@
  1042.  
  1043.  
  1044.  static void atacon_putc_2_plane( struct condata *conp, struct display *p,
  1045. -                                 int c, int y, int x, int mode)
  1046. +                                 int c, int y, int x)
  1047.  
  1048.  {    register u_char   *dest;
  1049.      register u_char   *cdat;
  1050. @@ -1996,16 +2159,19 @@
  1051.                                 : "a" (dest), "d" ((fdx & eorx) ^ bgx) );
  1052.      }
  1053.  
  1054. +
  1055. +#ifdef COLOR_UNDERLINING
  1056.      if (conp->vc_underline) {
  1057.          __asm__ __volatile__ ( "movepw %1,%0@(0)" : /* no outputs */
  1058.                                 : "a" (dest-bytes), "d" (fgx) );
  1059.      }
  1060. +#endif
  1061.  }
  1062.  
  1063.  
  1064.  static void atacon_putcs_2_plane( struct condata *conp, struct
  1065.                                    display *p, const char *s,
  1066. -                                  int count, int y, int x, int mode)
  1067. +                                  int count, int y, int x)
  1068.  
  1069.  {    register u_char   *dest, *dest0;
  1070.      register u_char   *cdat, c;
  1071. @@ -2031,10 +2197,12 @@
  1072.                                     : "a" (dest), "d" ((fdx & eorx) ^ bgx) );
  1073.          }
  1074.  
  1075. +#ifdef COLOR_UNDERLINING
  1076.          if (conp->vc_underline) {
  1077.              __asm__ __volatile__ ( "movepw %1,%0@(0)" : /* no outputs */
  1078.                                     : "a" (dest-bytes), "d" (fgx) );
  1079.          }
  1080. +#endif
  1081.  
  1082.          INC_2P(dest0);
  1083.      }
  1084. @@ -2255,7 +2423,7 @@
  1085.  
  1086.  
  1087.  static void atacon_putc_4_plane( struct condata *conp, struct display *p,
  1088. -                                 int c, int y, int x, int mode)
  1089. +                                 int c, int y, int x)
  1090.  {    register u_char   *dest;
  1091.      register u_char   *cdat;
  1092.      register int rows;
  1093. @@ -2278,16 +2446,18 @@
  1094.                                 : "a" (dest), "d" ((fdx & eorx) ^ bgx) );
  1095.      }
  1096.  
  1097. +#ifdef COLOR_UNDERLINING
  1098.      if (conp->vc_underline) {
  1099.          __asm__ __volatile__ ( "movepl %1,%0@(0)" : /* no outputs */
  1100.                                 : "a" (dest-bytes), "d" (fgx) );
  1101.      }
  1102. +#endif
  1103.  }
  1104.  
  1105.  
  1106.  static void atacon_putcs_4_plane( struct condata *conp, struct
  1107.                                    display *p, const char *s,
  1108. -                                  int count, int y, int x, int mode)
  1109. +                                  int count, int y, int x)
  1110.  {    register u_char   *dest, *dest0;
  1111.      register u_char   *cdat, c;
  1112.      register int rows;
  1113. @@ -2319,10 +2489,12 @@
  1114.                                     : "a" (dest), "d" ((fdx & eorx) ^ bgx) );
  1115.          }
  1116.  
  1117. +#ifdef COLOR_UNDERLINING
  1118.          if (conp->vc_underline) {
  1119.              __asm__ __volatile__ ( "movepl %1,%0@(0)" : /* no outputs */
  1120.                                     : "a" (dest-bytes), "d" (fgx) );
  1121.          }
  1122. +#endif
  1123.  
  1124.          INC_4P(dest0);
  1125.      }
  1126. @@ -2554,7 +2726,7 @@
  1127.  
  1128.  
  1129.  static void atacon_putc_8_plane( struct condata *conp, struct display *p,
  1130. -                                 int c, int y, int x, int mode)
  1131. +                                 int c, int y, int x)
  1132.  {    register u_char   *dest;
  1133.      register u_char   *cdat;
  1134.      register int rows;
  1135. @@ -2582,6 +2754,7 @@
  1136.              );
  1137.      }
  1138.  
  1139. +#ifdef COLOR_UNDERLINING
  1140.      if (conp->vc_underline) {
  1141.          __asm__ __volatile__
  1142.              ( "movepl %1,%0@(0)\n\t"
  1143. @@ -2590,12 +2763,13 @@
  1144.                : "a" (dest-bytes), "d" (fgx1), "d" (fgx2)
  1145.              );
  1146.      }
  1147. +#endif
  1148.  }
  1149.  
  1150.  
  1151.  static void atacon_putcs_8_plane( struct condata *conp, struct
  1152.                                    display *p, const char *s,
  1153. -                                  int count, int y, int x, int mode)
  1154. +                                  int count, int y, int x)
  1155.  
  1156.  {    register u_char   *dest, *dest0;
  1157.      register u_char   *cdat, c;
  1158. @@ -2634,6 +2808,7 @@
  1159.                  );
  1160.          }
  1161.  
  1162. +#ifdef COLOR_UNDERLINING
  1163.          if (conp->vc_underline) {
  1164.              __asm__ __volatile__
  1165.                  ( "movepl %1,%0@(0)\n\t"
  1166. @@ -2642,6 +2817,7 @@
  1167.                    : "a" (dest-bytes), "d" (fgx1), "d" (fgx2)
  1168.                  );
  1169.          }
  1170. +#endif
  1171.  
  1172.          INC_8P(dest0);
  1173.      }
  1174. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/atari/ataints.c linux-0.9pl4/atari/ataints.c
  1175. --- linux-0.9pl3/atari/ataints.c    Thu Sep 29 20:15:49 1994
  1176. +++ linux-0.9pl4/atari/ataints.c    Mon Nov 21 18:08:55 1994
  1177. @@ -51,24 +51,29 @@
  1178.  
  1179.  /* GK:
  1180.   * HBL IRQ handler for Falcon. Nobody needs it :-)
  1181. + * ++andreas: raise ipl to disable further interrupts.
  1182.   */
  1183.  asmlinkage void falcon_hblhandler(void);
  1184.  asm(".text
  1185. -     _falcon_hblhandler: rte");
  1186. +_falcon_hblhandler:
  1187. +    moveml    d0/a0,sp@-
  1188. +    btst    #4,sp@(14)    /* throwaway frame? */
  1189. +    beq    1f
  1190. +    movec    msp,a0        /* yes, use master stack */
  1191. +    bra    2f
  1192. +1:    lea    sp@(8),a0    /* else, use interrupt stack */
  1193. +2:    movew    a0@,d0
  1194. +    andw    #0xf8ff,d0
  1195. +    orw    #0x0200,d0    /* set saved ipl to 2 */
  1196. +    movew    d0,a0@
  1197. +    moveml    sp@+,d0/a0
  1198. +    rte");
  1199.  
  1200.  extern void atari_microwire_cmd( int cmd );
  1201.  
  1202.  void atari_init_INTS (void)
  1203.  
  1204.  {
  1205. -    int i;
  1206. -
  1207. -     /* GK: BSS is not cleared by bootstrap, so we must explicitly
  1208. -      * initialize the interrupt sources list
  1209. -      */
  1210. -     for( i = 0; i < NUM_ATARI_SOURCES; ++i )
  1211. -         ata_lists[i] = 0;
  1212. -    
  1213.      /* Initialize the MFP(s) */
  1214.      
  1215.      mfp.vec_adr  = 0x48;    /* Software EOI-Mode */
  1216. @@ -153,11 +158,37 @@
  1217.    return 1;
  1218.  }
  1219.  
  1220. +#if 0
  1221. +
  1222. +#include <linux/mm.h>
  1223. +extern unsigned long RCont;
  1224. +
  1225. +#define TEST_PAGE(str,adr)                                    \
  1226. +    do {                                                    \
  1227. +        unsigned long flags;                                \
  1228. +        save_flags(flags);; cli();                            \
  1229. +        if (*(unsigned long *)0xc03ff000 != RCont) {        \
  1230. +            printk("*0xc03ff000 = %08lx mem_map[]=%d\n",    \
  1231. +                   (RCont = *(unsigned long *)0xc03ff000),    \
  1232. +                   mem_map[MAP_NR(0xc03ff000)] );            \
  1233. +            printk("%s ",(str));                            \
  1234. +            printk("%08lx\n",(unsigned long)(adr));            \
  1235. +        }                                                    \
  1236. +        restore_flags(flags);                                \
  1237. +    } while(0)
  1238. +
  1239. +#else
  1240. +
  1241. +#define TEST_PAGE(str,adr) do {} while(0)
  1242. +
  1243. +#endif
  1244. +
  1245.  void atari_process_int (int level, struct intframe *fp)
  1246.  {
  1247.    ushort sr;
  1248.    int mask;
  1249.  
  1250. +TEST_PAGE("start irq level",level);
  1251.    /* Lower the ipl to let interrupts with higher priority come through */
  1252.    asm volatile ("movew sr,%0" : "=dm" (sr));
  1253.    sr -= 0x100;
  1254. @@ -168,6 +199,11 @@
  1255.  
  1256.    call_isr_list (ata_lists[level], fp);
  1257.  
  1258. +  /* Raise ipl again to avoid stacked interrupts.  */
  1259. +  asm volatile ("movew sr,%0" : "=dm" (sr));
  1260. +  sr += 0x100;
  1261. +  asm volatile ("movew %0,sr" : : "dm" (sr));
  1262. +
  1263.    /* acknowledge the interrupt */
  1264.    mask = ~(1 << (level & 7));
  1265.    switch (level >> 3)
  1266. @@ -186,7 +222,7 @@
  1267.        break;
  1268.      case 4:
  1269.      case 5:
  1270. -      /* TODO: SCC interrupt acknowledge */
  1271. +      scc.cha_a_ctrl = 070;    /* Reset highest IUS */
  1272.        break;
  1273.      }
  1274.  }
  1275. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/atari/atakeyb.c linux-0.9pl4/atari/atakeyb.c
  1276. --- linux-0.9pl3/atari/atakeyb.c    Sun Aug 14 10:30:00 1994
  1277. +++ linux-0.9pl4/atari/atakeyb.c    Mon Nov  7 22:07:47 1994
  1278. @@ -35,18 +35,26 @@
  1279.  /*
  1280.   * ++roman: The following changes were applied manually:
  1281.   *
  1282. - *  - The Alt (= Meta) key works in combination with Shift and Control, e.g. Alt+Shift+a sends Meta-A (0xc1),
  1283. - *    Alt+Control+A sends Meta-Ctrl-A (0x81) ...
  1284. + *  - The Alt (= Meta) key works in combination with Shift and
  1285. + *    Control, e.g. Alt+Shift+a sends Meta-A (0xc1), Alt+Control+A sends
  1286. + *    Meta-Ctrl-A (0x81) ...
  1287.   *
  1288. - *  - The parentheses on the keypad send '(' and ')' with all modifiers (as would do e.g. keypad '+'), but they cannot
  1289. - *    be used as application keys (i.e. sending Esc O c).
  1290. + *  - The parentheses on the keypad send '(' and ')' with all
  1291. + *    modifiers (as would do e.g. keypad '+'), but they cannot be used as
  1292. + *    application keys (i.e. sending Esc O c).
  1293.   *
  1294. - *  - HELP and UNDO are mapped to be F11 and F12, resp. This way, applications that allow their own keyboard mappings
  1295. - *    (e.g. tcsh, X Windows) can be configured to use them in the way the Label suggests (providing help or undoing).
  1296. + *  - HELP and UNDO are mapped to be F21 and F24, resp, that send the
  1297. + *    codes "\E[M" and "\E[P". (This is better than the old mapping to
  1298. + *    F11 and F12, because these codes are on Shift+F1/2 anyway.) This
  1299. + *    way, applications that allow their own keyboard mappings
  1300. + *    (e.g. tcsh, X Windows) can be configured to use them in the way
  1301. + *    the label suggests (providing help or undoing).
  1302.   *
  1303. - *  - Console switching is done with Alt+Fx (consoles 1..10) and Shift+Alt+Fx (consoles 11..20).
  1304. + *  - Console switching is done with Alt+Fx (consoles 1..10) and
  1305. + *    Shift+Alt+Fx (consoles 11..20).
  1306.   *
  1307. - *  - The misc. special function implemented in the kernel are mapped to the following key combinations:
  1308. + *  - The misc. special function implemented in the kernel are mapped
  1309. + *    to the following key combinations:
  1310.   *
  1311.   *      ClrHome          -> Home/Find
  1312.   *      Shift + ClrHome  -> End/Select
  1313. @@ -61,9 +69,13 @@
  1314.   *      Alt + Insert     -> stop/start output (same as ^S/^Q)
  1315.   *      Alt + Up         -> Scroll back console (if implemented)
  1316.   *      Alt + Down       -> Scroll forward console (if implemented)
  1317. + *      Alt + CapsLock   -> NumLock
  1318.   *
  1319.   */
  1320.  
  1321. +#define K_F21    K_MACRO
  1322. +#define K_F24    K_PAUSE
  1323. +
  1324.  unsigned short atakey_map[NR_KEYMAPS][NR_KEYS] = {
  1325.      { /* no modifiers */
  1326.  /* 00-03 */    K_HOLE,    '['&0x1f,    '1',    '2',
  1327. @@ -90,7 +102,7 @@
  1328.  /* 54-57 */    K_HOLE,    K_HOLE,    K_HOLE,    K_HOLE,
  1329.  /* 58-5b */    K_HOLE,    K_HOLE,    K_HOLE,    K_HOLE,
  1330.  /* 5c-5f */    K_HOLE,    K_HOLE,    K_HOLE,    K_HOLE,
  1331. -/* 60-63 */    '<',    K_F12,    K_HELP,    '(',
  1332. +/* 60-63 */    K_HOLE,    K_F24,    K_F21,    '(',
  1333.  /* 64-67 */    ')',    K_PSLASH,    K_PSTAR,    K_P7,
  1334.  /* 68-6b */    K_P8,    K_P9,    K_P4,    K_P5,
  1335.  /* 6c-6f */    K_P6,    K_P1,    K_P2,    K_P3,
  1336. @@ -123,7 +135,7 @@
  1337.  /* 54-57 */    K_HOLE,    K_HOLE,    K_HOLE,    K_HOLE,
  1338.  /* 58-5b */    K_HOLE,    K_HOLE,    K_HOLE,    K_HOLE,
  1339.  /* 5c-5f */    K_HOLE,    K_HOLE,    K_HOLE,    K_HOLE,
  1340. -/* 60-63 */    '>',    K_BREAK,    K_SH_MEM,    '(',
  1341. +/* 60-63 */    K_HOLE,    K_BREAK,    K_SH_MEM,    '(',
  1342.  /* 64-67 */    ')',    K_PSLASH,    K_PSTAR,    K_P7,
  1343.  /* 68-6b */    K_P8,    K_P9,    K_P4,    K_P5,
  1344.  /* 6c-6f */    K_P6,    K_P1,    K_P2,    K_P3,
  1345. @@ -222,7 +234,7 @@
  1346.  /* 54-57 */    K_HOLE,    K_HOLE,    K_HOLE,    K_HOLE,
  1347.  /* 58-5b */    K_HOLE,    K_HOLE,    K_HOLE,    K_HOLE,
  1348.  /* 5c-5f */    K_HOLE,    K_HOLE,    K_HOLE,    K_HOLE,
  1349. -/* 60-63 */    '\\'&0x1f,    K_HOLE,    K_SH_REGS,    '(',
  1350. +/* 60-63 */    K_HOLE,    K_F24,    K_SH_REGS,    '(',
  1351.  /* 64-67 */    ')',    K_PSLASH,    K_PSTAR,    K_P7,
  1352.  /* 68-6b */    K_P8,    K_P9,    K_P4,    K_P5,
  1353.  /* 6c-6f */    K_P6,    K_P1,    K_P2,    K_P3,
  1354. @@ -255,7 +267,7 @@
  1355.  /* 54-57 */    K_HOLE,    K_HOLE,    K_HOLE,    K_HOLE,
  1356.  /* 58-5b */    K_HOLE,    K_HOLE,    K_HOLE,    K_HOLE,
  1357.  /* 5c-5f */    K_HOLE,    K_HOLE,    K_HOLE,    K_HOLE,
  1358. -/* 60-63 */    K_HOLE,    K_HOLE,    K_HELP,    '(',
  1359. +/* 60-63 */    K_HOLE,    K_HOLE,    K_HOLE,    '(',
  1360.  /* 64-67 */    ')',    K_PSLASH,    K_PSTAR,    K_P7,
  1361.  /* 68-6b */    K_P8,    K_P9,    K_P4,    K_P5,
  1362.  /* 6c-6f */    K_P6,    K_P1,    K_P2,    K_P3,
  1363. @@ -344,7 +356,7 @@
  1364.  /* 2c-2f */    K(KT_META,'z'),    K(KT_META,'x'),    K(KT_META,'c'),    K(KT_META,'v'),
  1365.  /* 30-33 */    K(KT_META,'b'),    K(KT_META,'n'),    K(KT_META,'m'),    K(KT_META,','),
  1366.  /* 34-37 */    K(KT_META,'.'),    K(KT_META,'/'),    K_SHIFT,    K_HOLE,
  1367. -/* 38-3b */    K_ALT,    K(KT_META,' '),    K_CAPS,    K(KT_CONS,0),
  1368. +/* 38-3b */    K_ALT,    K(KT_META,' '),    K_NUM,    K(KT_CONS,0),
  1369.  /* 3c-3f */    K(KT_CONS,1),    K(KT_CONS,2),    K(KT_CONS,3),    K(KT_CONS,4),
  1370.  /* 40-43 */    K(KT_CONS,5),    K(KT_CONS,6),    K(KT_CONS,7),    K(KT_CONS,8),
  1371.  /* 44-47 */    K(KT_CONS,9),    K_HOLE,    K_HOLE,    K_FIND,
  1372. @@ -354,7 +366,7 @@
  1373.  /* 54-57 */    K_HOLE,    K_HOLE,    K_HOLE,    K_HOLE,
  1374.  /* 58-5b */    K_HOLE,    K_HOLE,    K_HOLE,    K_HOLE,
  1375.  /* 5c-5f */    K_HOLE,    K_HOLE,    K_HOLE,    K_HOLE,
  1376. -/* 60-63 */    K(KT_META,'<'),    K_CONS,    K_SH_STAT,    '(',
  1377. +/* 60-63 */    K_HOLE,    K_CONS,    K_SH_STAT,    '(',
  1378.  /* 64-67 */    ')',    K_PSLASH,    K_PSTAR,    K_ASC7,
  1379.  /* 68-6b */    K_ASC8,    K_ASC9,    K_ASC4,    K_ASC5,
  1380.  /* 6c-6f */    K_ASC6,    K_ASC1,    K_ASC2,    K_ASC3,
  1381. @@ -387,7 +399,7 @@
  1382.  /* 54-57 */    K_HOLE,    K_HOLE,    K_HOLE,    K_HOLE,
  1383.  /* 58-5b */    K_HOLE,    K_HOLE,    K_HOLE,    K_HOLE,
  1384.  /* 5c-5f */    K_HOLE,    K_HOLE,    K_HOLE,    K_HOLE,
  1385. -/* 60-63 */    K(KT_META,'>'),    K_HOLE,    K_HELP,    '(',
  1386. +/* 60-63 */    K_HOLE,    K_HOLE,    K_HOLE,    '(',
  1387.  /* 64-67 */    ')',    K_PSLASH,    K_PSTAR,    K_P7,
  1388.  /* 68-6b */    K_P8,    K_P9,    K_P4,    K_P5,
  1389.  /* 6c-6f */    K_P6,    K_P1,    K_P2,    K_P3,
  1390. @@ -486,7 +498,7 @@
  1391.  /* 54-57 */    K_HOLE,    K_HOLE,    K_HOLE,    K_HOLE,
  1392.  /* 58-5b */    K_HOLE,    K_HOLE,    K_HOLE,    K_HOLE,
  1393.  /* 5c-5f */    K_HOLE,    K_HOLE,    K_HOLE,    K_HOLE,
  1394. -/* 60-63 */    K(KT_META,'\\'&0x1f),    K_HOLE,    K_HELP,    '(',
  1395. +/* 60-63 */    K_HOLE,    K_HOLE,    K_HOLE,    '(',
  1396.  /* 64-67 */    ')',    K_PSLASH,    K_PSTAR,    K_P7,
  1397.  /* 68-6b */    K_P8,    K_P9,    K_P4,    K_P5,
  1398.  /* 6c-6f */    K_P6,    K_P1,    K_P2,    K_P3,
  1399. @@ -519,7 +531,7 @@
  1400.  /* 54-57 */    K_HOLE,    K_HOLE,    K_HOLE,    K_HOLE,
  1401.  /* 58-5b */    K_HOLE,    K_HOLE,    K_HOLE,    K_HOLE,
  1402.  /* 5c-5f */    K_HOLE,    K_HOLE,    K_HOLE,    K_HOLE,
  1403. -/* 60-63 */    K_HOLE,    K_HOLE,    K_HELP,    '(',
  1404. +/* 60-63 */    K_HOLE,    K_HOLE,    K_HOLE,    '(',
  1405.  /* 64-67 */    ')',    K_PSLASH,    K_PSTAR,    K_P7,
  1406.  /* 68-6b */    K_P8,    K_P9,    K_P4,    K_P5,
  1407.  /* 6c-6f */    K_P6,    K_P1,    K_P2,    K_P3,
  1408. @@ -552,7 +564,7 @@
  1409.  /* 54-57 */    K_HOLE,    K_HOLE,    K_HOLE,    K_HOLE,
  1410.  /* 58-5b */    K_HOLE,    K_HOLE,    K_HOLE,    K_HOLE,
  1411.  /* 5c-5f */    K_HOLE,    K_HOLE,    K_HOLE,    K_HOLE,
  1412. -/* 60-63 */    K_HOLE,    K_HOLE,    K_HELP,    K_HOLE,
  1413. +/* 60-63 */    K_HOLE,    K_HOLE,    K_HOLE,    K_HOLE,
  1414.  /* 64-67 */    K_HOLE,    K_PSLASH,    K_PSTAR,    K_P7,
  1415.  /* 68-6b */    K_P8,    K_P9,    K_P4,    K_P5,
  1416.  /* 6c-6f */    K_P6,    K_P1,    K_P2,    K_P3,
  1417. @@ -585,7 +597,7 @@
  1418.  /* 54-57 */    K_HOLE,    K_HOLE,    K_HOLE,    K_HOLE,
  1419.  /* 58-5b */    K_HOLE,    K_HOLE,    K_HOLE,    K_HOLE,
  1420.  /* 5c-5f */    K_HOLE,    K_HOLE,    K_HOLE,    K_HOLE,
  1421. -/* 60-63 */    K_HOLE,    K_HOLE,    K_HELP,    K_HOLE,
  1422. +/* 60-63 */    K_HOLE,    K_HOLE,    K_HOLE,    K_HOLE,
  1423.  /* 64-67 */    K_HOLE,    K_PSLASH,    K_PSTAR,    K_P7,
  1424.  /* 68-6b */    K_P8,    K_P9,    K_P4,    K_P5,
  1425.  /* 6c-6f */    K_P6,    K_P1,    K_P2,    K_P3,
  1426. @@ -615,69 +627,31 @@
  1427.  #define    DEFAULT_KEYB_REP_DELAY    (HZ/4)
  1428.  #define    DEFAULT_KEYB_REP_RATE    (HZ/25)
  1429.  
  1430. +/* These could be settable by some ioctl() in future... */
  1431.  unsigned int key_repeat_delay = DEFAULT_KEYB_REP_DELAY;
  1432.  unsigned int key_repeat_rate  = DEFAULT_KEYB_REP_RATE;
  1433.  
  1434. -
  1435. -#if 0
  1436. -
  1437. -/*
  1438. - * This table maps the Atari keyboard scan codes to
  1439. - * the Linux "virtual" scan codes.  These "virtual" scan
  1440. - * codes mostly conform to the scan codes given by an IBM
  1441. - * keyboard, except that the E0 xx codes are given unique
  1442. - * codes.  These are the codes > 96.  See linux/keyboard.h
  1443. - */
  1444. -
  1445. -static unsigned char atari_kmap[] =
  1446. -{
  1447. -/* 00-03 */    KB_NONE,       KB_ESCAPE,    KB_1,      KB_2,
  1448. -/* 04-07 */    KB_3,          KB_4,        KB_5,      KB_6,
  1449. -/* 08-0B */    KB_7,          KB_8,        KB_9,      KB_0,
  1450. -/* 0C-0F */    KB_DASH,       KB_EQUAL,     KB_BACKSPACE, KB_TAB,
  1451. -/* 10-13 */    KB_Q,          KB_W,        KB_E,      KB_R,
  1452. -/* 14-17 */    KB_T,          KB_Y,        KB_U,      KB_I,
  1453. -/* 18-1B */    KB_O,          KB_P,        KB_LSQUARE,   KB_RSQUARE,
  1454. -/* 1C-1F */    KB_ENTER,      KB_LCTRL,        KB_A,      KB_S,
  1455. -/* 20-23 */    KB_D,          KB_F,        KB_G,      KB_H,
  1456. -/* 24-27 */    KB_J,          KB_K,        KB_L,      KB_SEMICOLON,
  1457. -/* 28-2B */    KB_APOSTROPHE, KB_BACKQUOTE, KB_LSHIFT,    KB_BACKSLASH,
  1458. -/* 2C-2F */    KB_Z,          KB_X,        KB_C,      KB_V,
  1459. -/* 30-33 */    KB_B,          KB_N,        KB_M,         KB_COMMA,
  1460. -/* 34-37 */    KB_PERIOD,     KB_SLASH,     KB_RSHIFT,    KB_NONE,
  1461. -/* 38-3B */    KB_LALT,       KB_SPACE,     KB_CAPS,      KB_F1,
  1462. -/* 3C-3F */    KB_F2,         KB_F3,        KB_F4,      KB_F5,
  1463. -/* 40-43 */    KB_F6,         KB_F7,        KB_F8,      KB_F9,
  1464. -/* 44-47 */    KB_F10,        KB_NONE,      KB_NONE,      KB_FIND,
  1465. -/* 48-4B */    KB_UP,         KB_NONE,        KB_KPMINUS,   KB_LEFT,
  1466. -/* 4C-4F */    KB_NONE,       KB_RIGHT,     KB_KPPLUS,    KB_NONE,
  1467. -/* 50-53 */    KB_DOWN,       KB_NONE,        KB_INSERT,      KB_DELETE,
  1468. -/* 54-57 */    KB_NONE,          KB_NONE,        KB_NONE,      KB_NONE,
  1469. -/* 58-5B */    KB_NONE,          KB_NONE,        KB_NONE,      KB_NONE,
  1470. -/* 5B-5F */    KB_NONE,       KB_NONE,      KB_NONE,      KB_NONE,
  1471. -/* 60-63 */    KB_LESS,       KB_UNDO,      KB_HELP,      KB_KPLPAR,
  1472. -/* 64-67 */    KB_KPRPAR,     KB_KPDIVIDE,  KB_KPMULTIPLY,KB_KP7,
  1473. -/* 68-6B */    KB_KP8,        KB_KP9,        KB_KP4,      KB_KP5,
  1474. -/* 6C-6F */    KB_KP6,        KB_KP1,        KB_KP2,      KB_KP3,
  1475. -/* 70-73 */    KB_KP0,        KB_KPDECIMAL, KB_KPENTER,      KB_NONE,
  1476. -/* 74-77 */    KB_NONE,       KB_NONE,        KB_NONE,      KB_NONE,
  1477. -/* 78-7B */    KB_NONE,       KB_NONE,        KB_NONE,      KB_NONE,
  1478. -/* 7C-7F */    KB_NONE,       KB_NONE,        KB_NONE,      KB_NONE
  1479. -};
  1480. -
  1481. -#endif
  1482. -
  1483. -
  1484.  static unsigned char rep_scancode;
  1485.  static struct timer_list atakeyb_rep_timer = { NULL, NULL, 0, 0, atakeyb_rep };
  1486.  
  1487.  
  1488.  static void atakeyb_rep( unsigned long ignore )
  1489.  
  1490. -{
  1491. +{    unsigned long flags;
  1492. +    
  1493. +    /* process_scancode() mucks around with the tty queues without
  1494. +     * disabling interrupts! It assumes that it is called from an irq...
  1495. +     */
  1496. +    save_flags(flags);
  1497. +    cli();
  1498. +
  1499. +    del_timer( &atakeyb_rep_timer );
  1500.      atakeyb_rep_timer.expires = key_repeat_rate;
  1501.      add_timer( &atakeyb_rep_timer );
  1502. +
  1503.      process_scancode( rep_scancode );
  1504. +
  1505. +    restore_flags(flags);
  1506.  }
  1507.  
  1508.  
  1509. @@ -687,13 +661,22 @@
  1510.    int scancode;
  1511.    int break_flag;
  1512.  
  1513. + repeat:
  1514.    acia_stat = acia.key_ctrl;
  1515.    /* check out if the interrupt came from this ACIA */
  1516.    if (!(acia_stat & ACIA_IRQ))
  1517.      return;
  1518.  
  1519. +    if (acia_stat & ACIA_OVRN)
  1520. +    {
  1521. +    /* a very fast typist or a slow system, give a warning */
  1522. +    printk( "Keyboard overrun\n" );
  1523. +    goto get_key;
  1524. +    }
  1525. +
  1526.      if (acia_stat & ACIA_RDRF)    /* received a character */
  1527.      {
  1528. +    get_key:
  1529.      scancode = acia.key_data;    /* get it or reset the ACIA, I'll get it! */
  1530.      switch (kb_state.state)
  1531.      {
  1532. @@ -809,13 +792,13 @@
  1533.  
  1534.      if (acia_stat & (ACIA_FE | ACIA_PE))
  1535.      {
  1536. -    panic("Error in keyboard communication");
  1537. +    printk("Error in keyboard communication");
  1538.      }
  1539.  
  1540. -    if (acia_stat & ACIA_OVRN)
  1541. -    {
  1542. -    /* a very fast typist or a slow system, give a warning */    
  1543. -    }
  1544. +    /* process_scancode() can take a lot of time, so check again if
  1545. +     * some character arrived
  1546. +     */
  1547. +    goto repeat;
  1548.  }
  1549.  
  1550.  #ifdef KEYB_WRITE_INTERRUPT
  1551. @@ -1098,6 +1081,7 @@
  1552.      kb_state.len = 0;
  1553.  
  1554.      /* enable ACIA Interrupts */ 
  1555. +    mfp.active_edge &= ~0x10;
  1556.      mfp.int_en_b |= 0x40;
  1557.  
  1558.    return kmem_start;
  1559. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/atari/config.c linux-0.9pl4/atari/config.c
  1560. --- linux-0.9pl3/atari/config.c    Sun Aug 14 10:30:00 1994
  1561. +++ linux-0.9pl4/atari/config.c    Mon Nov 21 18:08:55 1994
  1562. @@ -33,6 +33,7 @@
  1563.  #include <linux/atariints.h>
  1564.  
  1565.  #include <asm/system.h>
  1566. +#include <asm/io.h>
  1567.  
  1568.  
  1569.  /* ++andreas: timer interrupt fixed to have perfect 100 Hz */
  1570. @@ -93,14 +94,14 @@
  1571.  
  1572.  #define    RTC_READ(reg)                            \
  1573.      ({    unsigned char    __val;                    \
  1574. -        tt_rtc.regsel = (reg);                    \
  1575. +        outb(reg,&tt_rtc.regsel);                \
  1576.          __val = tt_rtc.data;                    \
  1577.          __val;                                    \
  1578.      })
  1579.  
  1580.  #define    RTC_WRITE(reg,val)                        \
  1581.      do {                                        \
  1582. -        tt_rtc.regsel = (reg);                    \
  1583. +        outb(reg,&tt_rtc.regsel);                \
  1584.          tt_rtc.data = (val);                    \
  1585.      } while(0)
  1586.      
  1587. @@ -108,15 +109,11 @@
  1588.  void atari_gettod( struct mktime *time )
  1589.  
  1590.  {
  1591. -        int                i;
  1592.          unsigned char    ctrl;
  1593. +        unsigned short     tos_version;
  1594.          
  1595. -        for (i = 0 ; i < 1000000 ; i++)    /* may take up to 1 second... */
  1596. -            if (RTC_READ(RTC_FREQ_SELECT) & RTC_UIP)
  1597. -                break;
  1598. -        for (i = 0 ; i < 1000000 ; i++)    /* must try at least 2.228 ms*/
  1599. -            if (!(RTC_READ(RTC_FREQ_SELECT) & RTC_UIP))
  1600. -                break;
  1601. +        while (!(RTC_READ(RTC_FREQ_SELECT) & RTC_UIP)) ;
  1602. +        while (RTC_READ(RTC_FREQ_SELECT) & RTC_UIP) ;
  1603.  
  1604.          time->sec  = RTC_READ(RTC_SECONDS);
  1605.          time->min  = RTC_READ(RTC_MINUTES);
  1606. @@ -125,10 +122,6 @@
  1607.          time->mon  = RTC_READ(RTC_MONTH);
  1608.          time->year = RTC_READ(RTC_YEAR);
  1609.  
  1610. -        /* Adjust values (let the setup valid for TOS) */
  1611. -        time->mon--;
  1612. -        time->year += 68;
  1613. -
  1614.          ctrl = RTC_READ(RTC_CONTROL); 
  1615.  
  1616.          if (!(ctrl & RTC_DM_BINARY)) {
  1617. @@ -145,6 +138,11 @@
  1618.                  time->hour += 12;
  1619.              }
  1620.          }
  1621. +    /* Adjust values (let the setup valid) */
  1622. +    time->mon--;
  1623. +    /* Tos version at Physical 2 */
  1624. +    tos_version = *(unsigned short *)PTOV( 2 );
  1625. +    time->year += (tos_version < 0x306) ? 70 : 68;
  1626.  }
  1627.  
  1628.  
  1629. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/atari/joystick.c linux-0.9pl4/atari/joystick.c
  1630. --- linux-0.9pl3/atari/joystick.c    Sun Aug 14 10:30:33 1994
  1631. +++ linux-0.9pl4/atari/joystick.c    Mon Nov 21 18:08:55 1994
  1632. @@ -1,15 +1,21 @@
  1633.  /*
  1634.   * Atari Joystick Driver for Linux
  1635.   * by Robert de Vries (robert@and.nl) 19Jul93
  1636. + *
  1637. + * 16 Nov 1994 Andreas Schwab
  1638. + * Support for three button mouse (shamelessly stolen from MiNT)
  1639. + * third button wired to one of the joystick directions on joystick 1
  1640.   */
  1641.  
  1642.  #include <linux/sched.h>
  1643.  #include <linux/errno.h>
  1644.  #include <linux/atarikb.h>
  1645.  #include <linux/atari_joystick.h>
  1646. +#include <linux/atari_mouse.h>
  1647.  #include <asm/segment.h>
  1648.  
  1649.  static struct joystick_status joystick[2];
  1650. +extern int atari_mouse_buttons; /* for three-button mouse */
  1651.  
  1652.  void joystick_interrupt(char *buf)
  1653.  {
  1654. @@ -21,6 +27,18 @@
  1655.      joystick[j].fire  = (buf[1] & 0x80) >> 7;
  1656.      joystick[j].ready = 1;
  1657.      wake_up_interruptible(&joystick[j].wait);
  1658. +
  1659. +    /* For three-button mouse emulation fake a mouse packet */
  1660. +    if (j == 1 && (buf[1] & 1) != ((atari_mouse_buttons & 2) >> 1))
  1661. +      {
  1662. +    char faked_packet[3];
  1663. +
  1664. +    atari_mouse_buttons = (atari_mouse_buttons & 5) | ((buf[1] & 1) << 1);
  1665. +    faked_packet[0] = atari_mouse_buttons;
  1666. +    faked_packet[1] = 0;
  1667. +    faked_packet[2] = 0;
  1668. +    atari_mouse_interrupt (faked_packet);
  1669. +      }
  1670.  
  1671.  /*    ikbd_joystick_event_on(); */
  1672.  }
  1673. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/atari/stdma.c linux-0.9pl4/atari/stdma.c
  1674. --- linux-0.9pl3/atari/stdma.c    Tue Sep 27 22:21:22 1994
  1675. +++ linux-0.9pl4/atari/stdma.c    Tue Nov  8 18:31:59 1994
  1676. @@ -14,20 +14,31 @@
  1677.  /* This file contains some function for controlling the access to the  */
  1678.  /* ST-DMA chip that may be shared between devices. Currently we have:  */
  1679.  /*   TT:     Floppy and ACSI bus                                       */
  1680. -/*   Falcon: Floppy, SCSI and IDE                                      */
  1681. +/*   Falcon: Floppy and SCSI                                           */
  1682.  /*                                                                     */
  1683.  /* The controlling functions set up a wait queue for access to the     */
  1684.  /* ST-DMA chip. Callers to stdma_lock() that cannot granted access are */
  1685.  /* put onto a queue and waked up later if the owner calls              */
  1686.  /* stdma_release(). Additionally, the caller gives his interrupt       */
  1687.  /* service routine to stdma_lock().                                    */
  1688. +/*                                                                     */
  1689. +/* On the Falcon, the IDE bus uses just the ACSI/Floppy interrupt, but */
  1690. +/* not the ST-DMA chip itself. So falhd.c needs not to lock the        */
  1691. +/* chip. The interrupt is routed to falhd.c if IDE is configured, the  */
  1692. +/* model is a Falcon and the interrupt was caused by the HD controller */
  1693. +/* (can be determined by looking at its status register).              */
  1694. +
  1695.  
  1696. +#include <linux/config.h>
  1697.  #include <linux/types.h>
  1698. +#include <linux/genhd.h>
  1699.  #include <linux/sched.h>
  1700. +#include <linux/bootinfo.h>
  1701.  #include <linux/atari_stdma.h>
  1702.  #include <linux/atariints.h>
  1703.  #include <linux/atarihw.h>
  1704. -
  1705. +#include <linux/atarihdreg.h>
  1706. +#include <asm/io.h>
  1707.  
  1708.  static int        stdma_locked = 0;                /* the semaphore */
  1709.  static isrfunc    stdma_isr = NULL;                /* int func to be called */
  1710. @@ -40,6 +51,9 @@
  1711.  /***************************** Prototypes *****************************/
  1712.  
  1713.  static void stdma_int( struct intframe *fp, void *data );
  1714. +#ifdef CONFIG_ATARI_FALCON_IDE
  1715. +extern void hd_interrupt( struct intframe *fp, void *data );
  1716. +#endif
  1717.  
  1718.  /************************* End of Prototypes **************************/
  1719.  
  1720. @@ -125,6 +139,27 @@
  1721.  
  1722.  
  1723.  /*
  1724. + * Function: int stdma_islocked( void )
  1725. + *
  1726. + * Purpose: Check if the ST-DMA is currently locked.
  1727. + * Note: This function should be called only with interrupts disbabled
  1728. + *         to avoid race conditions. Also, the returned status is only
  1729. + *         valid as long as the ints remain disabled.
  1730. + *
  1731. + * Inputs: none
  1732. + *
  1733. + * Returns: != 0 if locked, 0 otherwise
  1734. + *
  1735. + */
  1736. +
  1737. +int stdma_islocked( void )
  1738. +
  1739. +{
  1740. +    return( stdma_locked );
  1741. +}
  1742. +
  1743. +
  1744. +/*
  1745.   * Function: void stdma_init( void )
  1746.   *
  1747.   * Purpose: Initialize the ST-DMA chip access controlling.
  1748. @@ -157,6 +192,12 @@
  1749.  static void stdma_int( struct intframe *fp, void *data )
  1750.  
  1751.  {
  1752. +#ifdef CONFIG_ATARI_FALCON_IDE
  1753. +  if (boot_info.bi_atari.model == ATARI_FALCON &&
  1754. +      (inb (HD_IRQ_TEST) & 0xad))
  1755. +      hd_interrupt( fp, data );
  1756. +  else
  1757. +#endif
  1758.      if (stdma_isr)
  1759.          (*stdma_isr)( fp, stdma_isr_data );
  1760.  }
  1761. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/atari/stram.c linux-0.9pl4/atari/stram.c
  1762. --- linux-0.9pl3/atari/stram.c    Sun Aug 14 10:30:34 1994
  1763. +++ linux-0.9pl4/atari/stram.c    Mon Nov  7 22:10:07 1994
  1764. @@ -1,8 +1,11 @@
  1765. +
  1766.  #include <linux/types.h>
  1767.  #include <linux/kernel.h>
  1768.  #include <linux/bootinfo.h>
  1769.  #include <linux/atarihw.h>
  1770.  
  1771. +#if 0
  1772. +
  1773.  struct stram_desc
  1774.    {
  1775.      unsigned first:1;
  1776. @@ -139,3 +142,99 @@
  1777.        edp = dp2;
  1778.      }
  1779.  }
  1780. +
  1781. +#else
  1782. +
  1783. +#include <linux/mm.h>
  1784. +
  1785. +/* ++roman:
  1786. + * 
  1787. + * New version of ST-Ram buffer allocation. Instead of using the
  1788. + * 1 MB - 4 KB that remain when the the ST-Ram chunk starts at $1000
  1789. + * (1 MB granularity!), such buffers are reserved like this:
  1790. + *
  1791. + *  - If the kernel resides in ST-Ram anyway, we can take the buffer
  1792. + *    from behind the current kernel data space the normal way
  1793. + *    (incrementing start_mem).
  1794. + *    
  1795. + *  - If the kernel is in TT-Ram, stram_init() initializes start and
  1796. + *    end of the available region. Buffers are allocated from there
  1797. + *    and mem_init() later marks the such used pages as reserved.
  1798. + *    Since each TT-Ram chunk is at least 4 MB in size, I hope there
  1799. + *    won't be an overrun of the ST-Ram region by normal kernel data
  1800. + *    space.
  1801. + *    
  1802. + * For that, ST-Ram may only be allocated while kernel initialization
  1803. + * is going on, or exactly: before mem_init() is called. There is also
  1804. + * no provision now for freeing ST-Ram buffers. It seems that isn't
  1805. + * really needed.
  1806. + *
  1807. + * ToDo:
  1808. + * Check the high level scsi code what is done when the
  1809. + * UNCHECKED_ISA_DMA flag is set. It guess, it is just a test for adr
  1810. + * < 16 Mega. There should be call to atari_stram_alloc() instead.
  1811. + *
  1812. + * Also ToDo:
  1813. + * Go through head.S and delete parts no longer needed (transparent
  1814. + * mapping of ST-Ram etc.)
  1815. + * 
  1816. + */
  1817. +   
  1818. +
  1819. +unsigned long rsvd_stram_beg, rsvd_stram_end;
  1820. +    /* Start and end of the reserved ST-Ram region */
  1821. +static unsigned long stram_end;
  1822. +    /* Overall end of ST-Ram */
  1823. +
  1824. +
  1825. +void atari_stram_init( void )
  1826. +
  1827. +{    int        i;
  1828. +
  1829. +    for( i = 0; i < boot_info.num_memory; ++i ) {
  1830. +        if (boot_info.memory[i].addr == 0) {
  1831. +            rsvd_stram_beg = PTOV( 0x800 ); /* skip super-only first 2 KB! */
  1832. +            rsvd_stram_end = rsvd_stram_beg;
  1833. +            stram_end = rsvd_stram_beg - 0x800 + boot_info.memory[i].size;
  1834. +            return;
  1835. +        }
  1836. +    }
  1837. +    /* Should never come here! (There is always ST-Ram!) */
  1838. +}
  1839. +
  1840. +
  1841. +void *atari_stram_alloc( long size, unsigned long *start_mem )
  1842. +
  1843. +{
  1844. +    static int                kernel_in_stram = -1;
  1845. +    
  1846. +    void    *adr = 0;
  1847. +    
  1848. +    if (kernel_in_stram < 0)
  1849. +        kernel_in_stram = (PTOV( 0 ) == KSTART_ADDR);
  1850. +
  1851. +    if (kernel_in_stram) {
  1852. +        /* Get memory from kernel data space */
  1853. +        adr = (void *) *start_mem;
  1854. +        *start_mem += size;
  1855. +    }
  1856. +    else {
  1857. +        /* Get memory from rsvd_stram_beg */
  1858. +        if (rsvd_stram_end + size < stram_end) {
  1859. +            adr = (void *) rsvd_stram_end;
  1860. +            rsvd_stram_end += size;
  1861. +        }
  1862. +    }
  1863. +    
  1864. +    return( adr );
  1865. +}
  1866. +
  1867. +void atari_stram_free( void *ptr )
  1868. +
  1869. +{
  1870. +    /* Sorry, this is a dummy. It isn't needed anyway. */
  1871. +}
  1872. +
  1873. +#endif
  1874. +
  1875. +
  1876. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/config.in linux-0.9pl4/config.in
  1877. --- linux-0.9pl3/config.in    Thu Sep 29 18:27:15 1994
  1878. +++ linux-0.9pl4/config.in    Fri Nov 11 21:01:08 1994
  1879. @@ -19,6 +19,7 @@
  1880.  if [ "$CONFIG_ATARI" = "y" ]
  1881.  bool 'Atari Falcon IDE harddisk support' CONFIG_ATARI_FALCON_IDE y
  1882.  bool 'Limit Floppy drive to DD only' CONFIG_FLOPPY_DD_ONLY n
  1883. +bool 'Atari ACSI support' CONFIG_ATARI_ACSI y
  1884.  fi
  1885.  bool 'TCP/IP networking' CONFIG_INET y
  1886.  bool 'Limit memory to low 16MB' CONFIG_MAX_16M n
  1887. @@ -106,7 +107,7 @@
  1888.  bool 'xiafs filesystem support' CONFIG_XIA_FS n
  1889.  bool 'msdos fs support' CONFIG_MSDOS_FS y
  1890.  bool '/proc filesystem support' CONFIG_PROC_FS y
  1891. -bool 'NFS filesystem support' CONFIG_NFS_FS n
  1892. +bool 'NFS filesystem support' CONFIG_NFS_FS y
  1893.  bool 'ISO9660 cdrom filesystem support' CONFIG_ISO9660_FS y
  1894.  bool 'System V and Coherent filesystem support' CONFIG_SYSV_FS n
  1895.  bool 'Amiga FFS filesystem support' CONFIG_AFFS_FS y
  1896. @@ -120,7 +121,7 @@
  1897.  if [ "$CONFIG_ATARI" = "y" ]
  1898.  bool 'Atari mouse support' CONFIG_ATARIMOUSE y
  1899.  fi
  1900. -bool 'Selection (cut and paste for virtual consoles)' CONFIG_SELECTION n
  1901. +bool 'Selection (cut and paste for virtual consoles)' CONFIG_SELECTION y
  1902.  bool 'QIC-02 tape support' CONFIG_TAPE_QIC02 n
  1903.  bool 'QIC-117 tape support' CONFIG_FTAPE n
  1904.  if [ "$CONFIG_FTAPE" = "y" ]
  1905. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/drivers/block/Makefile linux-0.9pl4/drivers/block/Makefile
  1906. --- linux-0.9pl3/drivers/block/Makefile    Sun Aug 14 10:30:43 1994
  1907. +++ linux-0.9pl4/drivers/block/Makefile    Mon Nov  7 22:11:26 1994
  1908. @@ -57,6 +57,11 @@
  1909.  SRCS := $(SRCS) xd.c
  1910.  endif
  1911.  
  1912. +ifdef CONFIG_ATARI_ACSI
  1913. +OBJS := $(OBJS) acsi.o
  1914. +SRCS := $(SRCS) acsi.c
  1915. +endif
  1916. +
  1917.  all: block.a
  1918.  
  1919.  block.a: $(OBJS)
  1920. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/drivers/block/acsi.c linux-0.9pl4/drivers/block/acsi.c
  1921. --- linux-0.9pl3/drivers/block/acsi.c    Wed Dec 31 19:00:00 1969
  1922. +++ linux-0.9pl4/drivers/block/acsi.c    Thu Nov 24 21:37:38 1994
  1923. @@ -0,0 +1,1442 @@
  1924. +/*
  1925. + * acsi.c -- Device driver for Atari ACSI hard disks
  1926. + *
  1927. + * Copyright 1994 Roman Hodek
  1928. + *   EMail: rnhodek@cip.informatik.uni-erlangen.de (Internet)
  1929. + *      or: Roman_Hodek@n.maus.de (MausNet, NO mail > 16 KB!)
  1930. + *
  1931. + * Some parts are based on hd.c by Linus Thorvalds
  1932. + *
  1933. + * This file is subject to the terms and conditions of the GNU General Public
  1934. + * License.  See the file README.legal in the main directory of this archive
  1935. + * for more details.
  1936. + *
  1937. + */
  1938. +
  1939. +/*
  1940. + * Still to in this file:
  1941. + *  - There is also the "bits get set somewhere while DMA" problem as
  1942. + *    with the floppy driver. See there. Maybe this is a hardware problem.
  1943. + *  - If a command ends with an error status (!= 0), the following
  1944. + *    REQUEST SENSE commands (4 to fill the ST-DMA FIFO) are done by
  1945. + *    polling the _IRQ signal (not interrupt-driven). This should be
  1946. + *    avoided in future because it takes up a non-neglectible time in
  1947. + *    the interrupt service routine while interrupts are disabled.
  1948. + *    Maybe a timer interrupt will get lost :-(
  1949. + */
  1950. +
  1951. +/*
  1952. + * General notes:
  1953. + *
  1954. + *  - All ACSI devices (disks, CD-ROMs, ...) use major number 28.
  1955. + *    Minors are organized like it is with SCSI: The upper 4 bits
  1956. + *    identify the device, the lower 4 bits the partition.
  1957. + *    The device numbers (the upper 4 bits) are given in the same
  1958. + *    order as the devices are found on the bus.
  1959. + *  - Up to 8 LUNs are supported for each target, but only a total of
  1960. + *    16 devices (due to minor numbers...). Note that Atari allows
  1961. + *    only a maximum of 4 targets (i.e. controllers, not devices) on
  1962. + *    the ACSI bus!
  1963. + *  - The SLM laser printer is not supported. In many ways, it behaves
  1964. + *    different than other ACSI devices and there are other problems,
  1965. + *    too (DMA size is not a multiple of 512, intervention necessary
  1966. + *    while DMA-ing the page data).
  1967. + *  - A optimizing scheme similar to SCSI scatter-gather is implemented.
  1968. + *  - Removable media are supported. After a medium change to device
  1969. + *    is reinitialized (partition check etc.). Also, if the device
  1970. + *    knows the PREVENT/ALLOW MEDIUM REMOVAL command, the door should
  1971. + *    be locked and unlocked when mounting the first or unmounting the
  1972. + *    last filesystem on the device. The code is untested, because I
  1973. + *    don't have a removable harddisk.
  1974. + *
  1975. + */
  1976. +
  1977. +#include <linux/errno.h>
  1978. +#include <linux/signal.h>
  1979. +#include <linux/sched.h>
  1980. +#include <linux/timer.h>
  1981. +#include <linux/fs.h>
  1982. +#include <linux/kernel.h>
  1983. +#include <linux/genhd.h>
  1984. +#include <linux/delay.h>
  1985. +
  1986. +#include <linux/bootinfo.h>
  1987. +#include <linux/interrupt.h>
  1988. +#include <linux/atarihw.h>
  1989. +#include <linux/atari_stdma.h>
  1990. +#include <linux/atari_rootsec.h>
  1991. +
  1992. +#include <asm/system.h>
  1993. +#include <asm/segment.h>
  1994. +
  1995. +#if 0
  1996. +extern unsigned long RCont;
  1997. +
  1998. +#define TEST_PAGE(str,adr)                                    \
  1999. +    do {                                                    \
  2000. +        unsigned long flags;                                \
  2001. +        save_flags(flags);; cli();                            \
  2002. +        if (*(unsigned long *)0xc03ff000 != RCont) {        \
  2003. +            printk("*0xc03ff000 = %08lx mem_map[]=%d\n",    \
  2004. +                   (RCont = *(unsigned long *)0xc03ff000),    \
  2005. +                   mem_map[MAP_NR(0xc03ff000)] );            \
  2006. +            printk("%s ",(str));                            \
  2007. +            printk("%08lx\n",(unsigned long)(adr));            \
  2008. +        }                                                    \
  2009. +        restore_flags(flags);                                \
  2010. +    } while(0)
  2011. +
  2012. +#else
  2013. +
  2014. +#define TEST_PAGE(str,adr) do {} while(0)
  2015. +
  2016. +#endif
  2017. +
  2018. +
  2019. +#define MAJOR_NR ACSI_MAJOR
  2020. +#include "blk.h"
  2021. +
  2022. +#define DEBUG
  2023. +#undef NO_WRITE
  2024. +
  2025. +#define MAX_ERRORS             8    /* Max read/write errors/sector */
  2026. +#define MAX_LUN                8    /* Max LUNs per target */
  2027. +#define MAX_DEV                   16
  2028. +
  2029. +#define ACSI_BUFFER_SIZE    (16*1024)
  2030. +#define ACSI_BUFFER_SECTORS    (ACSI_BUFFER_SIZE/512)
  2031. +
  2032. +#define ACSI_TIMEOUT        (4*HZ)
  2033. +
  2034. +
  2035. +typedef enum {
  2036. +    NONE, HARDDISK, CDROM
  2037. +} ACSI_TYPE;
  2038. +
  2039. +struct acsi_info_struct {
  2040. +    ACSI_TYPE        type;            /* type of device */
  2041. +    unsigned        target;            /* target number */
  2042. +    unsigned        lun;            /* LUN in target controller */
  2043. +    unsigned        removable : 1;    /* Flag for removable media */
  2044. +    unsigned        read_only : 1;    /* Flag for read only devices */
  2045. +    unsigned        changed : 1;    /* Medium has been changed */
  2046. +    unsigned long     size;            /* #blocks */
  2047. +} acsi_info[MAX_DEV];
  2048. +
  2049. +typedef struct {
  2050. +    unsigned long    dummy[2];
  2051. +    unsigned long    sector_size;
  2052. +    unsigned char    format_code;
  2053. +#define SENSE_FORMAT_FIX    1    
  2054. +#define SENSE_FORMAT_CHNG    2
  2055. +    unsigned char    cylinders_h;
  2056. +    unsigned char    cylinders_l;
  2057. +    unsigned char    heads;
  2058. +    unsigned char    reduced_h;
  2059. +    unsigned char    reduced_l;
  2060. +    unsigned char    precomp_h;
  2061. +    unsigned char    precomp_l;
  2062. +    unsigned char    landing_zone;
  2063. +    unsigned char    steprate;
  2064. +    unsigned char    type;
  2065. +#define SENSE_TYPE_FIXCHNG_MASK        4
  2066. +#define SENSE_TYPE_SOFTHARD_MASK    8
  2067. +#define SENSE_TYPE_FIX                4
  2068. +#define SENSE_TYPE_CHNG                0
  2069. +#define SENSE_TYPE_SOFT                0
  2070. +#define SENSE_TYPE_HARD                8
  2071. +    unsigned char    sectors;
  2072. +} SENSE_DATA;
  2073. +
  2074. +#define CAPACITY(sd)    (((int)((sd).cylinders_h<<8)|(sd).cylinders_l) * \
  2075. +                         (sd).heads * \
  2076. +                         (sd).sectors)
  2077. +
  2078. +static char             *acsi_buffer;
  2079. +static unsigned long     phys_acsi_buffer;
  2080. +static int                NDevices = 0;
  2081. +static int                acsi_sizes[MAX_DEV<<4] = { 0, };
  2082. +static int                acsi_blocksizes[MAX_DEV<<4] = { 0, };
  2083. +static struct hd_struct    acsi_part[MAX_DEV<<4] = { {0,0}, };
  2084. +static int                 access_count[MAX_DEV] = { 0, };
  2085. +static char             busy[MAX_DEV] = { 0, };
  2086. +static struct wait_queue *busy_wait;
  2087. +
  2088. +static int                CurrentNReq;
  2089. +static int                CurrentNSect;
  2090. +static char                *CurrentBuffer;
  2091. +
  2092. +
  2093. +#define ENABLE_IRQ()                            \
  2094. +    do {                                        \
  2095. +        mfp.int_pn_b = 0x7f;                    \
  2096. +        mfp.int_en_b |= 0x80;                    \
  2097. +    } while(0)
  2098. +
  2099. +#define DISABLE_IRQ()                            \
  2100. +    do {                                        \
  2101. +        mfp.int_en_b &= ~0x80;                    \
  2102. +    } while(0)
  2103. +
  2104. +#define SET_TIMER()                                \
  2105. +    do {                                        \
  2106. +        del_timer( &acsi_timer );                \
  2107. +        acsi_timer.expires = ACSI_TIMEOUT;        \
  2108. +        add_timer( &acsi_timer );                \
  2109. +    } while(0)
  2110. +
  2111. +#define CLEAR_TIMER()                            \
  2112. +    do {                                        \
  2113. +        del_timer( &acsi_timer );                \
  2114. +    } while(0)
  2115. +
  2116. +#define STRAM_ADDR(a)    (((a) & 0xff000000) == 0)
  2117. +
  2118. +
  2119. +
  2120. +/* ACSI commands */
  2121. +
  2122. +static char tur_cmd[6]        = { 0x00, 0, 0, 0, 0, 0 };
  2123. +static char modesense_cmd[6]  = { 0x1a, 0, 0, 0, 24, 0 };
  2124. +static char inquiry_cmd[6]    = { 0x12, 0, 0, 0, 16, 0 };
  2125. +static char reqsense_cmd[6]   = { 0x03, 0, 0, 0, 4, 0 };
  2126. +static char read_cmd[6]       = { 0x08, 0, 0, 0, 0, 0 };
  2127. +static char write_cmd[6]      = { 0x0a, 0, 0, 0, 0, 0 };
  2128. +static char pa_med_rem_cmd[6] = { 0x1e, 0, 0, 0, 0, 0 };
  2129. +
  2130. +#define CMDSET_TARG_LUN(cmd,targ,lun)            \
  2131. +    do {                                        \
  2132. +        cmd[0] = (cmd[0] & ~0xe0) | (targ)<<5;    \
  2133. +        cmd[1] = (cmd[1] & ~0xe0) | (lun)<<5;    \
  2134. +    } while(0)
  2135. +
  2136. +#define CMDSET_BLOCK(cmd,blk)                        \
  2137. +    do {                                            \
  2138. +        unsigned long __blk = (blk);                \
  2139. +        cmd[3] = __blk; __blk >>= 8;                \
  2140. +        cmd[2] = __blk; __blk >>= 8;                \
  2141. +        cmd[1] = (cmd[1] & 0xe0) | (__blk & 0x1f);    \
  2142. +    } while(0)
  2143. +
  2144. +#define CMDSET_LEN(cmd,len)                        \
  2145. +    do {                                        \
  2146. +        cmd[4] = (len);                            \
  2147. +    } while(0)
  2148. +
  2149. +#define min(a,b)    (((a)<(b))?(a):(b))
  2150. +
  2151. +
  2152. +/* ACSI errors (from REQUEST SENSE) */
  2153. +
  2154. +struct acsi_error {
  2155. +    unsigned char    code;
  2156. +    const char        *text;
  2157. +} acsi_errors[] = {
  2158. +    { 0x00, "No error (??)" },
  2159. +    { 0x01, "No index pulses" },
  2160. +    { 0x02, "Seek not complete" },
  2161. +    { 0x03, "Write fault" },
  2162. +    { 0x04, "Drive not ready" },
  2163. +    { 0x06, "No Track 00 signal" },
  2164. +    { 0x10, "ECC error in ID field" },
  2165. +    { 0x11, "Uncorrectable data error" },
  2166. +    { 0x12, "ID field address mark not found" },
  2167. +    { 0x13, "Data field address mark not found" },
  2168. +    { 0x14, "Record not found" },
  2169. +    { 0x15, "Seek error" },
  2170. +    { 0x18, "Data check in no retry mode" },
  2171. +    { 0x19, "ECC error during verify" },
  2172. +    { 0x1a, "Access to bad block" },
  2173. +    { 0x1c, "Unformatted or bad format" },
  2174. +    { 0x20, "Invalid command" },
  2175. +    { 0x21, "Invalid block address" },
  2176. +    { 0x23, "Volume overflow" },
  2177. +    { 0x24, "Invalid argument" },
  2178. +    { 0x25, "Invalid drive number" },
  2179. +    { 0x26, "Byte zero parity check" },
  2180. +    { 0x28, "Cartride changed" },
  2181. +    { 0x2c, "Error count overflow" },
  2182. +    { 0x30, "Controller selftest failed" }
  2183. +};
  2184. +
  2185. +
  2186. +/***************************** Prototypes *****************************/
  2187. +
  2188. +static int wait_for_IRQ( unsigned timeout );
  2189. +static int wait_for_noIRQ( unsigned timeout );
  2190. +static int acsicmd_dma( const char *cmd, char *buffer, int blocks, int
  2191. +                        rwflag );
  2192. +static int acsicmd_nodma( const char *cmd );
  2193. +static int acsi_reqsense( char *buffer );
  2194. +static int acsi_getstatus( void );
  2195. +static void acsi_print_error( const unsigned char *errblk );
  2196. +static void acsi_interrupt( struct intframe *fp, void *data );
  2197. +static void unexpected_acsi_interrupt( void );
  2198. +static void bad_rw_intr( void );
  2199. +static void read_intr( void );
  2200. +static void write_intr( void);
  2201. +static void acsi_times_out( unsigned long dummy );
  2202. +static void copy_to_acsibuffer( void );
  2203. +static void copy_from_acsibuffer( void );
  2204. +static void do_end_requests( void );
  2205. +static void do_acsi_request( void );
  2206. +static void redo_acsi_request( void );
  2207. +static int acsi_ioctl( struct inode *inode, struct file *file, unsigned int
  2208. +                       cmd, unsigned long arg );
  2209. +static int acsi_open( struct inode * inode, struct file * filp );
  2210. +static void acsi_release( struct inode * inode, struct file * file );
  2211. +static void acsi_prevent_removal( int target, int flag );
  2212. +static int acsi_mode_sense( int target, int lun, SENSE_DATA *sd );
  2213. +static void acsi_geninit( void );
  2214. +int revalidate_acsidisk( int dev, int maxusage );
  2215. +
  2216. +/************************* End of Prototypes **************************/
  2217. +
  2218. +
  2219. +struct timer_list acsi_timer = { NULL, NULL, 0, 0, acsi_times_out };
  2220. +
  2221. +
  2222. +
  2223. +/***********************************************************************
  2224. + *
  2225. + *   ACSI primitives
  2226. + *
  2227. + **********************************************************************/
  2228. +
  2229. +
  2230. +/*
  2231. + * The following two functions wait for _IRQ to become Low or High,
  2232. + * resp., with a timeout. The 'timeout' parameter is in jiffies
  2233. + * (10ms).
  2234. + * If the functions are called with timer interrupts on (int level <
  2235. + * 6), the timeout is based on the 'jiffies' variable to provide exact
  2236. + * timeouts for device probing etc.
  2237. + * If interrupts are disabled, the number of tries is based on the
  2238. + * 'loops_per_sec' variable. A rough estimation is sufficient here...
  2239. + */
  2240. +
  2241. +#define INT_LEVEL                                                    \
  2242. +    ({    unsigned __sr;                                                \
  2243. +        __asm__ __volatile__ ( "movew    sr,%0" : "=dm" (__sr) );    \
  2244. +        (__sr >> 8) & 7;                                            \
  2245. +    })
  2246. +
  2247. +static int wait_for_IRQ( unsigned timeout )
  2248. +
  2249. +{
  2250. +    if (INT_LEVEL < 6) {
  2251. +        unsigned long maxjif;
  2252. +        for( maxjif = jiffies + timeout; jiffies < maxjif; )
  2253. +            if (!(mfp.par_dt_reg & 0x20)) return( 1 );
  2254. +    }
  2255. +    else {
  2256. +        long tries = loops_per_sec / HZ / 8 * timeout;
  2257. +        while( --tries >= 0 )
  2258. +            if (!(mfp.par_dt_reg & 0x20)) return( 1 );
  2259. +    }        
  2260. +    return( 0 ); /* timeout! */
  2261. +}
  2262. +
  2263. +
  2264. +static int wait_for_noIRQ( unsigned timeout )
  2265. +
  2266. +{
  2267. +    if (INT_LEVEL < 6) {
  2268. +        unsigned long maxjif;
  2269. +        for( maxjif = jiffies + timeout; jiffies < maxjif; )
  2270. +            if (mfp.par_dt_reg & 0x20) return( 1 );
  2271. +    }
  2272. +    else {
  2273. +        long tries = loops_per_sec * timeout / HZ / 8;
  2274. +        while( tries-- >= 0 )
  2275. +            if (mfp.par_dt_reg & 0x20) return( 1 );
  2276. +    }        
  2277. +    return( 0 ); /* timeout! */
  2278. +}
  2279. +
  2280. +
  2281. +/* Send one data byte over the bus and set mode for next operation
  2282. + * with one move.l -- Atari recommends this...
  2283. + */
  2284. +
  2285. +#define DMA_LONG_WRITE(data,mode)                                                \
  2286. +    do {                                                                        \
  2287. +        *((unsigned long *)&dma_wd.fdc_acces_seccount) = ((data)<<16) | (mode);    \
  2288. +    } while(0)
  2289. +
  2290. +
  2291. +/* acsicmd_dma() sends an ACSI command and sets up the DMA to transfer
  2292. + * 'blocks' blocks of 512 bytes from/to 'buffer'.
  2293. + * Because the _IRQ signal is used for handshaking the command bytes,
  2294. + * the ACSI interrupt has to be disabled in this function. If the end
  2295. + * of the operation should be signalled by a real interrupt, it has to be
  2296. + * reenabled afterwards.
  2297. + */
  2298. +
  2299. +static int acsicmd_dma( const char *cmd, char *buffer, int blocks, int rwflag )
  2300. +
  2301. +{    unsigned long    flags, paddr;
  2302. +    int                i;
  2303. +
  2304. +#ifdef NO_WRITE
  2305. +    if (rwflag || *cmd == 0x0a) {
  2306. +        printk( "ACSI: Write commands disabled!\n" );
  2307. +        return( 0 );
  2308. +    }
  2309. +#endif
  2310. +    
  2311. +    rwflag = rwflag ? 0x100 : 0;
  2312. +    paddr = VTOP( buffer );
  2313. +
  2314. +    DISABLE_IRQ();
  2315. +
  2316. +    save_flags(flags);  
  2317. +    cli();
  2318. +    /* Low on A1 */
  2319. +    dma_wd.dma_mode_status = 0x88 | rwflag;
  2320. +    nop(); nop();
  2321. +
  2322. +    /* set DMA address */
  2323. +    dma_wd.dma_lo = (unsigned char)paddr;
  2324. +    paddr >>= 8;
  2325. +    nop();
  2326. +    dma_wd.dma_md = (unsigned char)paddr;
  2327. +    paddr >>= 8;
  2328. +    nop();
  2329. +    dma_wd.dma_hi = (unsigned char)paddr;
  2330. +    nop();
  2331. +    restore_flags(flags);
  2332. +
  2333. +    /* send the command bytes except the last */
  2334. +    for( i = 0; i < 5; ++i ) {
  2335. +        DMA_LONG_WRITE( *cmd++, 0x8a | rwflag );
  2336. +        udelay(20);
  2337. +        if (!wait_for_IRQ( HZ/2 )) return( 0 ); /* timeout */
  2338. +    }
  2339. +
  2340. +    /* Clear FIFO and switch DMA to correct direction */  
  2341. +    dma_wd.dma_mode_status = 0x90 | (rwflag ^ 0x100);  
  2342. +    nop();
  2343. +    dma_wd.dma_mode_status = 0x90 | rwflag;
  2344. +    nop();
  2345. +
  2346. +    /* How many sectors for DMA */
  2347. +    dma_wd.fdc_acces_seccount = blocks;
  2348. +    nop();
  2349. +    
  2350. +    /* send last command byte */
  2351. +    dma_wd.dma_mode_status = 0x8a | rwflag;
  2352. +    nop();
  2353. +    DMA_LONG_WRITE( *cmd++, 0x0a | rwflag );
  2354. +    udelay(80);
  2355. +
  2356. +    return( 1 );
  2357. +    /* Note that the ACSI interrupt is still disabled after this
  2358. +     * function. If you want to get the IRQ delivered, enable it manually!
  2359. +     */
  2360. +}
  2361. +
  2362. +
  2363. +/*
  2364. + * acsicmd_nodma() sends an ACSI command that requires no DMA.
  2365. + */
  2366. +
  2367. +static int acsicmd_nodma( const char *cmd )
  2368. +
  2369. +{    int    i;
  2370. +
  2371. +    DISABLE_IRQ();
  2372. +
  2373. +    /* send first command byte */
  2374. +    dma_wd.dma_mode_status = 0x88;
  2375. +    nop(); nop();
  2376. +    DMA_LONG_WRITE( *cmd++, 0x8a );
  2377. +    udelay(20);
  2378. +    if (!wait_for_IRQ( HZ/2 )) return( 0 ); /* timeout */
  2379. +
  2380. +    /* send the intermediate command bytes */
  2381. +    for( i = 0; i < 4; ++i ) {
  2382. +        DMA_LONG_WRITE( *cmd++, 0x8a );
  2383. +        udelay(20);
  2384. +        if (!wait_for_IRQ( HZ/2 )) return( 0 ); /* timeout */
  2385. +    }
  2386. +
  2387. +    /* send last command byte */
  2388. +    DMA_LONG_WRITE( *cmd++, 0x0a );
  2389. +    udelay(80);
  2390. +    
  2391. +    return( 1 );
  2392. +    /* Note that the ACSI interrupt is still disabled after this
  2393. +     * function. If you want to get the IRQ delivered, enable it manually!
  2394. +     */
  2395. +}
  2396. +
  2397. +
  2398. +#ifdef DEBUG
  2399. +
  2400. +/* REQUEST SENSE is called only when DEBUG is defined to better
  2401. + * specify the error that occured.
  2402. + * Under normal circumstances, the exact error reason doesn't matter
  2403. + * and this function isn't needed.
  2404. + */
  2405. +
  2406. +static int acsi_reqsense( char *buffer )
  2407. +
  2408. +{
  2409. +    if (!acsicmd_dma( reqsense_cmd, buffer, 1, 0 )) return( 0 );
  2410. +    if (!wait_for_IRQ( 10 )) return( 0 );
  2411. +    acsi_getstatus();
  2412. +    udelay(100);
  2413. +    if (!acsicmd_nodma( reqsense_cmd )) return( 0 );
  2414. +    if (!wait_for_IRQ( 10 )) return( 0 );
  2415. +    acsi_getstatus();
  2416. +    udelay(100);
  2417. +    if (!acsicmd_nodma( reqsense_cmd )) return( 0 );
  2418. +    if (!wait_for_IRQ( 10 )) return( 0 );
  2419. +    acsi_getstatus();
  2420. +    udelay(100);
  2421. +    if (!acsicmd_nodma( reqsense_cmd )) return( 0 );
  2422. +    if (!wait_for_IRQ( 10 )) return( 0 );
  2423. +    acsi_getstatus();
  2424. +    cache_clear( VTOP(buffer), 16 );
  2425. +    
  2426. +    return( 1 );
  2427. +}    
  2428. +
  2429. +#endif
  2430. +
  2431. +
  2432. +/*
  2433. + * ACSI status phase: get the status byte from the bus
  2434. + *
  2435. + * I've seen several times that a 0xff status is read, propably due to
  2436. + * a timing error. In this case, the procedure is repeated after the
  2437. + * next _IRQ edge.
  2438. + */
  2439. +
  2440. +static int acsi_getstatus( void )
  2441. +
  2442. +{    int    status;
  2443. +
  2444. +    for(;;) {
  2445. +        if (!wait_for_IRQ( 40 )) return( -1 );
  2446. +        dma_wd.dma_mode_status = 0x8a;
  2447. +        nop(); nop();
  2448. +        status = dma_wd.fdc_acces_seccount;
  2449. +        if (status != 0xff) break;
  2450. +#ifdef DEBUG
  2451. +        printk("ACSI: skipping 0xff status byte\n" );
  2452. +#endif
  2453. +        udelay(40);
  2454. +        wait_for_noIRQ( 20 );
  2455. +    }
  2456. +    dma_wd.dma_mode_status = 0x80;
  2457. +    udelay(40);
  2458. +    wait_for_noIRQ( 20 );
  2459. +
  2460. +    return( status & 0x1f ); /* mask of the device# */
  2461. +}
  2462. +
  2463. +
  2464. +#if 0
  2465. +
  2466. +/* Receive data in an extended status phase. Never needed... */
  2467. +
  2468. +static int acsi_extstatus( char *buffer, int cnt )
  2469. +
  2470. +{    int    status, i = 0;
  2471. +
  2472. +    udelay(80);
  2473. +    while( cnt-- >= 0 ) {
  2474. +        if (!wait_for_IRQ( 40 )) return( 0 );
  2475. +        dma_wd.dma_mode_status = 0x8a;
  2476. +        nop(); nop();
  2477. +        status = dma_wd.fdc_acces_seccount;
  2478. +        *buffer++ = status & 0xff;
  2479. +        udelay(80);
  2480. +    }
  2481. +    return( 1 );
  2482. +}
  2483. +
  2484. +#endif
  2485. +
  2486. +
  2487. +static void acsi_print_error( const unsigned char *errblk )
  2488. +
  2489. +{    int i, errcode = errblk[0] & 0x7f;
  2490. +    
  2491. +    printk( "ACSI error 0x%02x", errcode );
  2492. +    if (errblk[0] & 0x80)
  2493. +        printk( " for sector %d",
  2494. +                ((errblk[1] & 0x1f) << 16) |
  2495. +                (errblk[2] << 8) | errblk[0] );
  2496. +    for( i = sizeof(acsi_errors)/sizeof(*acsi_errors)-1; i >= 0; --i )
  2497. +        if (acsi_errors[i].code == errcode) break;
  2498. +    if (i >= 0)
  2499. +        printk( ": %s\n", acsi_errors[i].text );
  2500. +}
  2501. +
  2502. +
  2503. +
  2504. +
  2505. +/*******************************************************************
  2506. + *
  2507. + * ACSI interrupt routine
  2508. + *   Test, if this is a ACSI interrupt and call the irq handler
  2509. + *   Otherwise ignore this interrupt.
  2510. + *
  2511. + *******************************************************************/
  2512. +
  2513. +static void acsi_interrupt( struct intframe *fp, void *data )
  2514. +
  2515. +{    void (*acsi_irq_handler)(void) = DEVICE_INTR;
  2516. +
  2517. +    DEVICE_INTR = NULL;
  2518. +    CLEAR_TIMER();
  2519. +
  2520. +    if (!acsi_irq_handler)
  2521. +        acsi_irq_handler = unexpected_acsi_interrupt;
  2522. +    acsi_irq_handler();
  2523. +}
  2524. +
  2525. +
  2526. +/******************************************************************
  2527. + *
  2528. + * The Interrupt handlers
  2529. + *
  2530. + *******************************************************************/
  2531. +
  2532. +
  2533. +static void unexpected_acsi_interrupt( void )
  2534. +
  2535. +{
  2536. +    printk("Unexpected ACSI interrupt\n");
  2537. +}
  2538. +
  2539. +
  2540. +/* This function is called in case of errors. Because we cannot reset
  2541. + * the ACSI bus or a single device, there is no other choice than
  2542. + * retrying several times :-(
  2543. + */
  2544. +
  2545. +static void bad_rw_intr( void )
  2546. +
  2547. +{
  2548. +    if (!CURRENT)
  2549. +        return;
  2550. +
  2551. +    if (++CURRENT->errors >= MAX_ERRORS)
  2552. +        end_request(0);
  2553. +    /* Otherwise just retry */
  2554. +}
  2555. +
  2556. +
  2557. +static void read_intr( void )
  2558. +
  2559. +{    int        status;
  2560. +    
  2561. +    status = acsi_getstatus();
  2562. +    if (status != 0) {
  2563. +        printk( "ad%c: ", DEVICE_NR(MINOR(CURRENT->dev))+'a' );
  2564. +        if (!acsi_reqsense( acsi_buffer ))
  2565. +            printk( "ACSI error and REQUEST SENSE failed (status=0x%02x)\n", status );
  2566. +        else {
  2567. +            acsi_print_error( acsi_buffer );
  2568. +            if ((*acsi_buffer & 0x7f) == 0x28)
  2569. +                acsi_info[DEVICE_NR(MINOR(CURRENT->dev))].changed = 1;
  2570. +        }
  2571. +        ENABLE_IRQ();
  2572. +        bad_rw_intr();
  2573. +        redo_acsi_request();
  2574. +        return;
  2575. +    }
  2576. +
  2577. +    cache_clear( VTOP(CurrentBuffer), CurrentNSect*512 );
  2578. +    if (CurrentBuffer == acsi_buffer)
  2579. +        copy_from_acsibuffer();
  2580. +
  2581. +    do_end_requests();
  2582. +    redo_acsi_request();
  2583. +}
  2584. +
  2585. +
  2586. +static void write_intr(void)
  2587. +
  2588. +{    int    status;
  2589. +
  2590. +    status = acsi_getstatus();
  2591. +    if (status != 0) {
  2592. +        printk( "ad%c: ", DEVICE_NR(MINOR(CURRENT->dev))+'a' );
  2593. +        if (!acsi_reqsense( acsi_buffer ))
  2594. +            printk( "ACSI error and REQUEST SENSE failed (status=0x%02x)\n", status );
  2595. +        else {
  2596. +            acsi_print_error( acsi_buffer );
  2597. +            if ((*acsi_buffer & 0x7f) == 0x28)
  2598. +                acsi_info[DEVICE_NR(MINOR(CURRENT->dev))].changed = 1;
  2599. +        }
  2600. +        bad_rw_intr();
  2601. +        redo_acsi_request();
  2602. +        return;
  2603. +    }
  2604. +
  2605. +    do_end_requests();
  2606. +    redo_acsi_request();
  2607. +}
  2608. +
  2609. +
  2610. +static void acsi_times_out( unsigned long dummy )
  2611. +
  2612. +{
  2613. +    DEVICE_INTR = NULL;
  2614. +    printk("ACSI timeout\n");
  2615. +    if (!CURRENT) return;
  2616. +    if (++CURRENT->errors >= MAX_ERRORS) {
  2617. +#ifdef DEBUG
  2618. +        printk("ACSI: too many errors.\n");
  2619. +#endif
  2620. +        end_request(0);
  2621. +    }
  2622. +
  2623. +    redo_acsi_request();
  2624. +}
  2625. +
  2626. +
  2627. +
  2628. +/***********************************************************************
  2629. + *
  2630. + *  Scatter-gather utility functions
  2631. + *
  2632. + ***********************************************************************/
  2633. +
  2634. +
  2635. +static void copy_to_acsibuffer( void )
  2636. +
  2637. +{    int                    i;
  2638. +    char                *src, *dst;
  2639. +    struct buffer_head    *bh;
  2640. +    
  2641. +    src = CURRENT->buffer;
  2642. +    dst = acsi_buffer;
  2643. +    bh = CURRENT->bh;
  2644. +
  2645. +    if (!bh)
  2646. +        memcpy( dst, src, CurrentNSect*512 );
  2647. +    else
  2648. +        for( i = 0; i < CurrentNReq; ++i ) {
  2649. +            memcpy( dst, src, bh->b_size );
  2650. +            dst += bh->b_size;
  2651. +            if ((bh = bh->b_reqnext))
  2652. +                src = bh->b_data;
  2653. +        }
  2654. +}
  2655. +
  2656. +
  2657. +static void copy_from_acsibuffer( void )
  2658. +
  2659. +{    int                    i;
  2660. +    char                *src, *dst;
  2661. +    struct buffer_head    *bh;
  2662. +    
  2663. +    dst = CURRENT->buffer;
  2664. +    src = acsi_buffer;
  2665. +    bh = CURRENT->bh;
  2666. +
  2667. +    if (!bh)
  2668. +        memcpy( dst, src, CurrentNSect*512 );
  2669. +    else
  2670. +        for( i = 0; i < CurrentNReq; ++i ) {
  2671. +            memcpy( dst, src, bh->b_size );
  2672. +            src += bh->b_size;
  2673. +            if ((bh = bh->b_reqnext))
  2674. +                dst = bh->b_data;
  2675. +        }
  2676. +}
  2677. +
  2678. +
  2679. +static void do_end_requests( void )
  2680. +
  2681. +{    int        i, n;
  2682. +
  2683. +    if (!CURRENT->bh) {
  2684. +        CURRENT->nr_sectors -= CurrentNSect;
  2685. +        CURRENT->current_nr_sectors -= CurrentNSect;
  2686. +        CURRENT->sector += CurrentNSect;
  2687. +        if (CURRENT->nr_sectors == 0)
  2688. +            end_request(1);
  2689. +    }
  2690. +    else {
  2691. +        for( i = 0; i < CurrentNReq; ++i ) {
  2692. +            n = CURRENT->bh->b_size >> 9;
  2693. +            CURRENT->nr_sectors -= n;
  2694. +            CURRENT->current_nr_sectors -= n;
  2695. +            CURRENT->sector += n;
  2696. +            end_request(1);
  2697. +        }
  2698. +    }
  2699. +}
  2700. +
  2701. +
  2702. +
  2703. +
  2704. +/***********************************************************************
  2705. + *
  2706. + *  do_acsi_request and friends
  2707. + *
  2708. + ***********************************************************************/
  2709. +
  2710. +static void do_acsi_request( void )
  2711. +
  2712. +{
  2713. +    stdma_lock( acsi_interrupt, NULL );
  2714. +    redo_acsi_request();
  2715. +}
  2716. +
  2717. +
  2718. +static void redo_acsi_request( void )
  2719. +
  2720. +{    unsigned            block, dev, target, lun, nsect;
  2721. +    char                 *buffer;
  2722. +    unsigned long        pbuffer;
  2723. +    struct buffer_head    *bh;
  2724. +    
  2725. +    TEST_PAGE("redo_acsi_request",0);
  2726. +    
  2727. +    if (CURRENT && CURRENT->dev < 0) {
  2728. +        if (!DEVICE_INTR) stdma_release();
  2729. +        return;
  2730. +    }
  2731. +
  2732. +    if (DEVICE_INTR)
  2733. +        return;
  2734. +
  2735. +  repeat:
  2736. +    CLEAR_TIMER();
  2737. +    /* Another check here: An interrupt or timer event could have
  2738. +     * happened since the last check!
  2739. +     */
  2740. +    if (CURRENT && CURRENT->dev < 0) {
  2741. +        if (!DEVICE_INTR) stdma_release();
  2742. +        return;
  2743. +    }
  2744. +    if (DEVICE_INTR)
  2745. +        return;
  2746. +
  2747. +    if (!CURRENT) {
  2748. +        CLEAR_INTR;
  2749. +        stdma_release();
  2750. +        return;
  2751. +    }
  2752. +    
  2753. +    if (MAJOR(CURRENT->dev) != MAJOR_NR)
  2754. +        panic(DEVICE_NAME ": request list destroyed");
  2755. +    if (CURRENT->bh) {
  2756. +        if (!CURRENT->bh->b_lock)
  2757. +            panic(DEVICE_NAME ": block not locked");
  2758. +    }
  2759. +
  2760. +    dev = MINOR(CURRENT->dev);
  2761. +    block = CURRENT->sector;
  2762. +    if (DEVICE_NR(dev) >= NDevices ||
  2763. +        block+CURRENT->nr_sectors >= acsi_part[dev].nr_sects) {
  2764. +#ifdef DEBUG
  2765. +        printk( "ad%c: attempted access for block %d past end of device at block %ld.\n",
  2766. +                DEVICE_NR(dev)+'a', block, acsi_part[dev].nr_sects);
  2767. +#endif
  2768. +        end_request(0);
  2769. +        goto repeat;
  2770. +    }
  2771. +    if (acsi_info[DEVICE_NR(dev)].changed) {
  2772. +        printk( "ad%c: request denied because cartridge has been changed.\n",
  2773. +                DEVICE_NR(dev)+'a' );
  2774. +        end_request(0);
  2775. +        goto repeat;
  2776. +    }
  2777. +    
  2778. +    block += acsi_part[dev].start_sect;
  2779. +    target = acsi_info[DEVICE_NR(dev)].target;
  2780. +    lun    = acsi_info[DEVICE_NR(dev)].lun;
  2781. +
  2782. +    /* Find out how many sectors should be transferred from/to
  2783. +     * consecutive buffers and thus can be done with a single command.
  2784. +     */
  2785. +    buffer      = CURRENT->buffer;
  2786. +    pbuffer     = VTOP(buffer);
  2787. +    nsect       = CURRENT->current_nr_sectors;
  2788. +    CurrentNReq = 1;
  2789. +
  2790. +    if ((bh = CURRENT->bh) && bh != CURRENT->bhtail) {
  2791. +        if (!STRAM_ADDR(pbuffer)) {
  2792. +            /* If transfer is done via the ACSI buffer anyway, we can
  2793. +             * assemble as much bh's as fit in the buffer.
  2794. +             */
  2795. +            while( (bh = bh->b_reqnext) ) {
  2796. +                if (nsect + (bh->b_size>>9) > ACSI_BUFFER_SECTORS) break;
  2797. +                nsect += bh->b_size >> 9;
  2798. +                ++CurrentNReq;
  2799. +                if (bh == CURRENT->bhtail) break;
  2800. +            }
  2801. +            buffer = acsi_buffer;
  2802. +        }
  2803. +        else {
  2804. +            unsigned long pendadr, pnewadr;
  2805. +            pendadr = pbuffer + nsect*512;
  2806. +            while( (bh = bh->b_reqnext) ) {
  2807. +                pnewadr = VTOP(bh->b_data);
  2808. +                if (!STRAM_ADDR(pnewadr) || pendadr != pnewadr) break;
  2809. +                nsect += bh->b_size >> 9;
  2810. +                pendadr += pnewadr + bh->b_size;
  2811. +                ++CurrentNReq;
  2812. +                if (bh == CURRENT->bhtail) break;
  2813. +            }
  2814. +        }
  2815. +    }
  2816. +    else {
  2817. +        if (!STRAM_ADDR(pbuffer)) {
  2818. +            buffer = acsi_buffer;
  2819. +            if (nsect > ACSI_BUFFER_SECTORS)
  2820. +                nsect = ACSI_BUFFER_SECTORS;
  2821. +        }
  2822. +    }
  2823. +    CurrentBuffer = buffer;
  2824. +    CurrentNSect  = nsect;
  2825. +    
  2826. +    if (CURRENT->cmd == WRITE) {
  2827. +        CMDSET_TARG_LUN( write_cmd, target, lun );
  2828. +        CMDSET_BLOCK( write_cmd, block );
  2829. +        CMDSET_LEN( write_cmd, nsect );
  2830. +        if (buffer == acsi_buffer)
  2831. +            copy_to_acsibuffer();
  2832. +        cache_push( pbuffer, nsect*512 );
  2833. +        if (!acsicmd_dma( write_cmd, buffer, nsect, 1 )) {
  2834. +            printk( "ACSI: Timeout in command block\n" );
  2835. +            udelay(200);    /* wait some time between commands to let
  2836. +                             * things settle down... */
  2837. +            bad_rw_intr();
  2838. +            goto repeat;
  2839. +        }
  2840. +        SET_INTR(write_intr);
  2841. +        SET_TIMER();
  2842. +        ENABLE_IRQ();
  2843. +        return;
  2844. +    }
  2845. +    if (CURRENT->cmd == READ) {
  2846. +        CMDSET_TARG_LUN( read_cmd, target, lun );
  2847. +        CMDSET_BLOCK( read_cmd, block );
  2848. +        CMDSET_LEN( read_cmd, nsect );
  2849. +        if (!acsicmd_dma( read_cmd, buffer, nsect, 0 )) {
  2850. +            printk( "ACSI: Timeout in command block\n" );
  2851. +            udelay(200);    /* wait some time between commands to let
  2852. +                             * things settle down... */
  2853. +            bad_rw_intr();
  2854. +            goto repeat;
  2855. +        }
  2856. +        SET_INTR(read_intr);
  2857. +        SET_TIMER();
  2858. +        ENABLE_IRQ();
  2859. +        return;
  2860. +    }
  2861. +    panic("unknown ACSI command");
  2862. +}
  2863. +
  2864. +
  2865. +
  2866. +/***********************************************************************
  2867. + *
  2868. + *  Misc functions: ioctl, open, release, check_change, ...
  2869. + *
  2870. + ***********************************************************************/
  2871. +
  2872. +
  2873. +static int acsi_ioctl( struct inode *inode, struct file *file,
  2874. +                       unsigned int cmd, unsigned long arg )
  2875. +{    int dev, err;
  2876. +
  2877. +    if (!inode)
  2878. +        return -EINVAL;
  2879. +    dev = DEVICE_NR(MINOR(inode->i_rdev));
  2880. +    if (dev >= NDevices)
  2881. +        return -EINVAL;
  2882. +    switch (cmd) {
  2883. +        /* I left out the GETGEO cmd; This doesn't make much sense for
  2884. +         * ACSI disks...
  2885. +         */
  2886. +      case BLKGETSIZE:   /* Return device size */
  2887. +        if (!arg)  return -EINVAL;
  2888. +        err = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long));
  2889. +        if (err)
  2890. +            return err;
  2891. +        put_fs_long(acsi_part[MINOR(inode->i_rdev)].nr_sects,
  2892. +                    (long *) arg);
  2893. +        return 0;
  2894. +      case BLKFLSBUF:
  2895. +        if(!suser())  return -EACCES;
  2896. +        if(!inode->i_rdev) return -EINVAL;
  2897. +        fsync_dev(inode->i_rdev);
  2898. +        invalidate_buffers(inode->i_rdev);
  2899. +        return 0;
  2900. +
  2901. +      case BLKRRPART: /* Re-read partition tables */
  2902. +        return revalidate_acsidisk(inode->i_rdev, 1);
  2903. +      RO_IOCTLS(inode->i_rdev,arg);
  2904. +      default:
  2905. +        return -EINVAL;
  2906. +    }
  2907. +}
  2908. +
  2909. +
  2910. +/*
  2911. + * Open a device, check for read-only and lock the medium if it is
  2912. + * removable.
  2913. + */
  2914. +
  2915. +static int acsi_open( struct inode * inode, struct file * filp )
  2916. +
  2917. +{    int target;
  2918. +    target = DEVICE_NR(MINOR(inode->i_rdev));
  2919. +
  2920. +    while (busy[target])
  2921. +        sleep_on(&busy_wait);
  2922. +
  2923. +    if (access_count[target] == 0 && acsi_info[target].removable) {
  2924. +        check_disk_change( inode->i_rdev );
  2925. +        acsi_prevent_removal( target, 1 );
  2926. +    }
  2927. +    access_count[target]++;
  2928. +
  2929. +    if (filp && filp->f_mode) {
  2930. +        if (filp->f_mode & 2) {
  2931. +            if (acsi_info[target].read_only) {
  2932. +                acsi_release( inode, filp );
  2933. +                return( -EACCES );
  2934. +            }
  2935. +        }
  2936. +    }
  2937. +
  2938. +    return 0;
  2939. +}
  2940. +
  2941. +/*
  2942. + * Releasing a block device means we sync() it, so that it can safely
  2943. + * be forgotten about...
  2944. + */
  2945. +
  2946. +static void acsi_release( struct inode * inode, struct file * file )
  2947. +
  2948. +{    int target;
  2949. +    
  2950. +    sync_dev(inode->i_rdev);
  2951. +
  2952. +    target = DEVICE_NR(MINOR(inode->i_rdev));
  2953. +    if (--access_count[target] == 0 && acsi_info[target].removable)
  2954. +        acsi_prevent_removal( target, 0 );
  2955. +}
  2956. +
  2957. +
  2958. +/*
  2959. + * Prevent or allow a media change for removable devices.
  2960. + */
  2961. +
  2962. +static void acsi_prevent_removal( int target, int flag )
  2963. +
  2964. +{
  2965. +    stdma_lock( NULL, NULL );
  2966. +    
  2967. +    CMDSET_TARG_LUN( pa_med_rem_cmd,
  2968. +                     acsi_info[target].target,
  2969. +                     acsi_info[target].lun );
  2970. +    CMDSET_LEN( pa_med_rem_cmd, flag );
  2971. +    
  2972. +    if (!acsicmd_nodma( pa_med_rem_cmd )) goto the_end;
  2973. +    if (!wait_for_IRQ( 3*HZ )) goto the_end;
  2974. +    acsi_getstatus();
  2975. +    /* Do not report errors -- some devices may not know this command. */
  2976. +
  2977. +  the_end:
  2978. +    ENABLE_IRQ();
  2979. +    stdma_release();
  2980. +}
  2981. +
  2982. +
  2983. +int check_acsi_media_change( int full_dev, int flag )
  2984. +
  2985. +{    int target = DEVICE_NR(MINOR(full_dev));
  2986. +    
  2987. +    if (!acsi_info[target].removable) return( 0 );
  2988. +
  2989. +    if (acsi_info[target].changed)
  2990. +        /* We can be sure that the medium has been changed -- REQUEST
  2991. +         * SENSE has reported this earlier.
  2992. +         */
  2993. +        return( 1 );
  2994. +
  2995. +    /* If the flag isn't set, make a test by reading block 0.
  2996. +     * If errors happen, it seems to be better to say "changed"...
  2997. +     */
  2998. +    stdma_lock( NULL, NULL );
  2999. +    CMDSET_TARG_LUN( read_cmd, acsi_info[target].target, acsi_info[target].lun );
  3000. +    CMDSET_BLOCK( read_cmd, 0 );
  3001. +    CMDSET_LEN( read_cmd, 1 );
  3002. +    if (acsicmd_dma( read_cmd, acsi_buffer, 1, 0 ) &&
  3003. +        wait_for_IRQ( HZ )) {
  3004. +        if (acsi_getstatus()) {
  3005. +            if (acsi_reqsense( acsi_buffer )) {
  3006. +                if ((acsi_buffer[0] & 0x7f) == 0x28)
  3007. +                    acsi_info[target].changed = 1;
  3008. +            }
  3009. +            else {
  3010. +                printk( "ad%c: REQUEST SENSE failed in test for medium change; assuming a change\n",
  3011. +                        target+'a' );
  3012. +                acsi_info[target].changed = 1;
  3013. +            }
  3014. +        }
  3015. +    }
  3016. +    else {
  3017. +        printk( "ad%c: Test for medium changed timed out; assuming a change\n",
  3018. +                target+'a' );
  3019. +        acsi_info[target].changed = 1;
  3020. +    }
  3021. +    ENABLE_IRQ();
  3022. +    stdma_release();
  3023. +
  3024. +    /* Now, after reading a block, the changed status is surely valid. */
  3025. +    return( acsi_info[target].changed );
  3026. +}
  3027. +
  3028. +
  3029. +static int acsi_mode_sense( int target, int lun, SENSE_DATA *sd )
  3030. +
  3031. +{
  3032. +    CMDSET_TARG_LUN( modesense_cmd, target, lun );
  3033. +    if (!acsicmd_dma( modesense_cmd, acsi_buffer, 1, 0 ) ||
  3034. +        !wait_for_IRQ( 3*HZ ) ||
  3035. +        acsi_getstatus() != 0 ||
  3036. +        /* read twice to jump over the second 16-byte border! */
  3037. +        (udelay(300), !wait_for_noIRQ( 20 )) ||
  3038. +        !acsicmd_nodma( modesense_cmd ) ||
  3039. +        !wait_for_IRQ( 3*HZ ) ||
  3040. +        acsi_getstatus() != 0) {
  3041. +        return( 0 );
  3042. +    }
  3043. +
  3044. +    cache_clear( phys_acsi_buffer, sizeof(SENSE_DATA) );
  3045. +    *sd = *(SENSE_DATA *)acsi_buffer;
  3046. +    if (CAPACITY(*sd) == 0) {
  3047. +#ifdef DEBUG
  3048. +        int i;
  3049. +        printk( "Mode sense data for ACSI target %d, lun %d seem not valid:",
  3050. +                target, lun );
  3051. +        for( i = 0; i < sizeof(SENSE_DATA); ++i )
  3052. +            printk( "%02x ", (unsigned char)acsi_buffer[i] );
  3053. +        printk( "\n" );
  3054. +#endif
  3055. +        return( 0 );
  3056. +    }
  3057. +    return( 1 );
  3058. +}
  3059. +
  3060. +
  3061. +
  3062. +/*******************************************************************
  3063. + *
  3064. + *  Initialization
  3065. + *
  3066. + ********************************************************************/
  3067. +
  3068. +
  3069. +static struct gendisk acsi_gendisk = {
  3070. +    MAJOR_NR,            /* Major number */    
  3071. +    "ad",                /* Major name */
  3072. +    4,                    /* Bits to shift to get real from partition */
  3073. +    1 << 4,                /* Number of partitions per real */
  3074. +    MAX_DEV,            /* maximum number of real */
  3075. +    acsi_geninit,        /* init function */
  3076. +    acsi_part,            /* hd struct */
  3077. +    acsi_sizes,            /* block sizes */
  3078. +    0,                    /* number */
  3079. +    (void *)acsi_info,    /* internal */
  3080. +    NULL                /* next */
  3081. +};
  3082. +    
  3083. +
  3084. +static void acsi_geninit( void )
  3085. +
  3086. +{    int             i;
  3087. +    int             target, lun, status;
  3088. +    ACSI_TYPE        type;
  3089. +    int                rmf, rdonly, got_inquiry;
  3090. +    SENSE_DATA        sense;
  3091. +    unsigned long    size;
  3092. +    
  3093. +    printk ("Probing ACSI devices:\n");
  3094. +    NDevices = 0;
  3095. +    stdma_lock( NULL, NULL );
  3096. +
  3097. +    for( target = 0; target < 8 && NDevices < MAX_DEV; ++target ) {
  3098. +
  3099. +        lun = 0;
  3100. +      repeat_for_lun:
  3101. +
  3102. +        /* Do a TEST UNIT READY command to test the presence of a
  3103. +         * device
  3104. +         */
  3105. +        CMDSET_TARG_LUN( tur_cmd, target, lun );
  3106. +        if (!acsicmd_nodma( tur_cmd ))
  3107. +            /* timed out -> no device here */
  3108. +            continue;
  3109. +        status = acsi_getstatus();
  3110. +        if (status) {
  3111. +            if (status == 0x12)
  3112. +                /* The SLM printer should be the only device that
  3113. +                 * responds with the error code in the status byte. In
  3114. +                 * correct status bytes, bit 4 is never set.
  3115. +                 */
  3116. +                printk( "  ID %d, LUN %d: SLM printer (not supported)\n",
  3117. +                        target, lun );
  3118. +            continue;
  3119. +        }
  3120. +
  3121. +        /* Assume default values */
  3122. +        type = HARDDISK;
  3123. +        rmf = 0;
  3124. +        rdonly = 0;
  3125. +        got_inquiry = 0;
  3126. +        printk( "  ID %d, LUN %d: ", target, lun );
  3127. +
  3128. +        /* Do an INQUIRY command to get more infos on this device;
  3129. +         * some older Atari disks don't know about INQUIRY, so use the
  3130. +         * defaults above in case of error...
  3131. +         */
  3132. +        udelay(200);
  3133. +        CMDSET_TARG_LUN( inquiry_cmd, target, lun );
  3134. +        if (acsicmd_dma( inquiry_cmd, acsi_buffer, 1, 0 ) &&
  3135. +            acsi_getstatus() == 0) {
  3136. +
  3137. +            cache_clear( phys_acsi_buffer, 32 );
  3138. +            
  3139. +            switch( acsi_buffer[0] ) {
  3140. +              case 0:
  3141. +                break;
  3142. +              case 5:
  3143. +                type = CDROM;
  3144. +                rdonly = 1;
  3145. +                break;
  3146. +              default:
  3147. +                printk( "Device type not supported (%d)\n", acsi_buffer[0] );
  3148. +                continue;
  3149. +            }
  3150. +            rmf = !!(acsi_buffer[1] & 0x80); /* removable? */
  3151. +            got_inquiry = 1;
  3152. +        }
  3153. +
  3154. +        udelay(200);
  3155. +        if (!acsi_mode_sense( target, lun, &sense )) {
  3156. +            printk( "No mode sense data.\n" );
  3157. +            continue;
  3158. +        }
  3159. +        if (sense.sector_size != 512) {
  3160. +            printk( "Sector size != 512 not supported.\n" );
  3161. +            continue;
  3162. +        }
  3163. +        size = CAPACITY(sense);
  3164. +        if (!got_inquiry) {
  3165. +            /* If INQUIRY wasn't successful, determine the type from
  3166. +             * the sense data.
  3167. +             */
  3168. +            if (sense.format_code == SENSE_FORMAT_CHNG &&
  3169. +                (sense.type & SENSE_TYPE_FIXCHNG_MASK) == SENSE_TYPE_CHNG)
  3170. +                rmf = 1;
  3171. +        }
  3172. +
  3173. +#if 0
  3174. +        /* Read sector 0 (the root sector) to get the media size.
  3175. +         * !! This has to be replaced by some better method! This data
  3176. +         * is only valid for Atari partitioned disks!
  3177. +         */
  3178. +        udelay(200);
  3179. +        CMDSET_TARG_LUN( read_cmd, target, lun );
  3180. +        CMDSET_BLOCK( read_cmd, 0 );
  3181. +        CMDSET_LEN( read_cmd, 1 );
  3182. +        if (!acsicmd_dma( read_cmd, acsi_buffer, 1, 0 ) ||
  3183. +            !wait_for_IRQ( 3*HZ ) ||
  3184. +            acsi_getstatus() != 0) {
  3185. +            printk( "Unreadable\n" );
  3186. +            continue;
  3187. +        }
  3188. +        cache_clear( phys_acsi_buffer, 512 );
  3189. +        size = ((struct rootsector *)acsi_buffer)->hd_siz;
  3190. +#endif
  3191. +        
  3192. +        /* Fill in the acsi_info for this device... */
  3193. +        acsi_info[NDevices].type      = type;
  3194. +        acsi_info[NDevices].target    = target;
  3195. +        acsi_info[NDevices].lun       = lun;
  3196. +        acsi_info[NDevices].removable = rmf;
  3197. +        acsi_info[NDevices].read_only = rdonly;
  3198. +        acsi_info[NDevices].changed   = 0;
  3199. +        acsi_info[NDevices].size      = size;
  3200. +
  3201. +        /* ...and inform the user about it. */
  3202. +        switch( type ) {
  3203. +          case HARDDISK:
  3204. +            printk( "Harddisk " );
  3205. +            break;
  3206. +          case CDROM:
  3207. +            printk( "CD-ROM " );
  3208. +            break;
  3209. +          default:
  3210. +            printk( "Type %d ", (int)type );
  3211. +            break;
  3212. +        }
  3213. +        if (rmf) printk( "(removable) " );
  3214. +        if (rdonly) printk( "(read-only) " );
  3215. +        printk( "%ld MByte\n", (size*512+1024*1024/2)/(1024*1024) );
  3216. +        
  3217. +        NDevices++;
  3218. +
  3219. +        /* If a test for this target was successful, try the next LUN, too */
  3220. +        if (++lun < MAX_LUN)
  3221. +            goto repeat_for_lun;
  3222. +    }
  3223. +
  3224. +    /* reenable interrupt */
  3225. +    ENABLE_IRQ();
  3226. +    stdma_release();
  3227. +
  3228. +    printk( "Found %d ACSI device(s) total.\n", NDevices );
  3229. +                     
  3230. +    for( i = 0; i < NDevices; ++i ) {
  3231. +        acsi_part[i<<4].start_sect = 0;
  3232. +        acsi_part[i<<4].nr_sects = acsi_info[i].size;
  3233. +    }
  3234. +    acsi_gendisk.nr_real = NDevices;
  3235. +    for( i = 0; i < (MAX_DEV << 4); i++ )
  3236. +        acsi_blocksizes[i] = 1024;
  3237. +    blksize_size[MAJOR_NR] = acsi_blocksizes;
  3238. +}
  3239. +
  3240. +
  3241. +static struct file_operations acsi_fops = {
  3242. +    NULL,            /* lseek - default */
  3243. +    block_read,        /* read - general block-dev read */
  3244. +    block_write,    /* write - general block-dev write */
  3245. +    NULL,            /* readdir - bad */
  3246. +    NULL,            /* select */
  3247. +    acsi_ioctl,        /* ioctl */
  3248. +    NULL,            /* mmap */
  3249. +    acsi_open,        /* open */
  3250. +    acsi_release,    /* release */
  3251. +    block_fsync        /* fsync */
  3252. +};
  3253. +
  3254. +
  3255. +unsigned long acsi_init( unsigned long mem_start, unsigned long mem_end )
  3256. +
  3257. +{
  3258. +    if (boot_info.machtype != MACH_ATARI ||
  3259. +        boot_info.bi_atari.model == ATARI_FALCON)
  3260. +        /* Do not init ACSI on a Falcon -- the port is used for SCSI there! */
  3261. +        return( mem_start );
  3262. +
  3263. +    if (register_blkdev( MAJOR_NR, "ad", &acsi_fops )) {
  3264. +        printk( "Unable to get major %d for ACSI\n", MAJOR_NR );
  3265. +        return( mem_start );
  3266. +    }
  3267. +
  3268. +    if (!(acsi_buffer = atari_stram_alloc( ACSI_BUFFER_SIZE, &mem_start ))) {
  3269. +        printk( "Unable to get ACSI ST-Ram buffer.\n" );
  3270. +        return( mem_start );
  3271. +    }
  3272. +    phys_acsi_buffer = VTOP( acsi_buffer );
  3273. +    
  3274. +    blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
  3275. +    read_ahead[MAJOR_NR] = 8;        /* 8 sector (4kB) read-ahead */
  3276. +    acsi_gendisk.next = gendisk_head;
  3277. +    gendisk_head = &acsi_gendisk;
  3278. +
  3279. +    return( mem_start );
  3280. +}
  3281. +
  3282. +
  3283. +#define DEVICE_BUSY busy[target]
  3284. +#define USAGE access_count[target]
  3285. +#define GENDISK_STRUCT acsi_gendisk
  3286. +
  3287. +/*
  3288. + * This routine is called to flush all partitions and partition tables
  3289. + * for a changed scsi disk, and then re-read the new partition table.
  3290. + * If we are revalidating a disk because of a media change, then we
  3291. + * enter with usage == 0.  If we are using an ioctl, we automatically have
  3292. + * usage == 1 (we need an open channel to use an ioctl :-), so this
  3293. + * is our limit.
  3294. + */
  3295. +
  3296. +int revalidate_acsidisk( int dev, int maxusage )
  3297. +
  3298. +{    int target, major;
  3299. +    struct gendisk * gdev;
  3300. +    int max_p;
  3301. +    int start;
  3302. +    int i;
  3303. +    SENSE_DATA sense;
  3304. +    
  3305. +    target =  DEVICE_NR(MINOR(dev));
  3306. +    gdev = &GENDISK_STRUCT;
  3307. +
  3308. +    cli();
  3309. +    if (DEVICE_BUSY || USAGE > maxusage) {
  3310. +        sti();
  3311. +        return -EBUSY;
  3312. +    };
  3313. +    DEVICE_BUSY = 1;
  3314. +    sti();
  3315. +
  3316. +    max_p = gdev->max_p;
  3317. +    start = target << gdev->minor_shift;
  3318. +    major = MAJOR_NR << 8;
  3319. +
  3320. +    for( i = max_p - 1; i >= 0 ; i-- ) {
  3321. +        sync_dev( major | start | i );
  3322. +        invalidate_inodes( major | start | i );
  3323. +        invalidate_buffers( major | start | i );
  3324. +        gdev->part[start+i].start_sect = 0;
  3325. +        gdev->part[start+i].nr_sects = 0;
  3326. +    };
  3327. +
  3328. +#if 0
  3329. +    /* Read sector 0 and look into the partitioning data to get the
  3330. +     * device size.
  3331. +     * !! This has to be replaced sometimes by a better method!
  3332. +     * Not all devices must be partitioned in Atari format!
  3333. +     */
  3334. +    bh = bread( dev, 0, 1024 );
  3335. +    if (!bh) {
  3336. +        printk( "ACSI device %04x: unable to read root sector\n", dev );
  3337. +        acsi_info[target].size = 0x1fffff;
  3338. +    }
  3339. +    else {
  3340. +        acsi_info[target].size = ((struct rootsector *)bh->b_data)->hd_siz;
  3341. +        brelse( bh );
  3342. +    }
  3343. +#else
  3344. +    stdma_lock( NULL, NULL );
  3345. +    if (!acsi_mode_sense( acsi_info[target].target, acsi_info[target].lun, &sense )) {
  3346. +        printk( "ACSI device %04x: mode sense failed.\n", dev );
  3347. +        acsi_info[target].size = 0x1fffff;
  3348. +    }
  3349. +    else {
  3350. +        acsi_info[target].size = CAPACITY(sense);
  3351. +    }
  3352. +    ENABLE_IRQ();
  3353. +    stdma_release();
  3354. +#endif
  3355. +    
  3356. +    acsi_info[target].changed = 0;
  3357. +
  3358. +    gdev->part[start].nr_sects = acsi_info[target].size;
  3359. +    resetup_one_dev( gdev, target );
  3360. +
  3361. +    DEVICE_BUSY = 0;
  3362. +    wake_up(&busy_wait);
  3363. +    return 0;
  3364. +}
  3365. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/drivers/block/amiflop.c linux-0.9pl4/drivers/block/amiflop.c
  3366. --- linux-0.9pl3/drivers/block/amiflop.c    Mon Aug 15 19:20:24 1994
  3367. +++ linux-0.9pl4/drivers/block/amiflop.c    Sat Nov 12 11:35:00 1994
  3368. @@ -44,8 +44,8 @@
  3369.   */
  3370.  #define FD_NODRIVE    0x00000000  /* response when no unit is present */
  3371.  #define FD_DD_3     0xffffffff  /* double-density 3.5" (880K) drive */
  3372. -#define FD_HD_3     0xaaaaaaaa  /* high-density 3.5" (1760K) drive */
  3373. -#define FD_DD_5     0x55555555  /* double-density 5.25" (440K) drive */
  3374. +#define FD_HD_3     0x55555555  /* high-density 3.5" (1760K) drive */
  3375. +#define FD_DD_5     0xaaaaaaaa  /* double-density 5.25" (440K) drive */
  3376.  
  3377.  
  3378.  /*
  3379. @@ -87,6 +87,8 @@
  3380.  
  3381.  /* track buffer */
  3382.  static int savedtrack = -1;
  3383. +static int writepending = 0;
  3384. +static int writefromint = 0;
  3385.  static unsigned char trackdata[MAX_SECTORS * 512];
  3386.  static char *raw_buf;
  3387.  
  3388. @@ -104,10 +106,6 @@
  3389.  static struct wait_queue *fdc_wait = NULL;
  3390.  static struct wait_queue *motor_wait = NULL;
  3391.  
  3392. -#if 0
  3393. -static unsigned int changed_floppies = 0;
  3394. -#endif
  3395. -
  3396.  /*
  3397.   * Functions
  3398.   */
  3399. @@ -138,6 +136,8 @@
  3400.      restore_flags(flags);
  3401.  }
  3402.  
  3403. +static struct timer_list flush_track_timer;
  3404. +
  3405.  static struct timer_list motor_on_timer;
  3406.  static struct timer_list motor_off_timer[FD_MAX_UNITS];
  3407.  static int on_attempts;
  3408. @@ -623,6 +623,8 @@
  3409.          unit[drive].track = -1;
  3410.          selected = -1;
  3411.          savedtrack = -1;
  3412. +        writepending = 0; /* if this was true before, too bad! */
  3413. +        writefromint = 0;
  3414.          return 1;
  3415.      }
  3416.      return 0;
  3417. @@ -688,13 +690,15 @@
  3418.      custom.dsklen = len/sizeof(short) | DSKLEN_DMAEN|DSKLEN_WRITE;
  3419.  
  3420.      block_flag = 2;
  3421. -    while (block_flag == 2)
  3422. -        sleep_on (&wait_fd_block);
  3423. +    return 1;
  3424. +}
  3425.  
  3426. +static void post_write (void)
  3427. +{
  3428.      udelay (2000);   /* 2ms post-write delay */
  3429.      custom.dsklen = 0;
  3430. -
  3431. -    return 1;
  3432. +  writepending = 0;
  3433. +  writefromint = 0;
  3434.  }
  3435.  
  3436.  static int get_track(int drive, int track)
  3437. @@ -719,12 +723,39 @@
  3438.      }
  3439.  }
  3440.  
  3441. +static void flush_track_callback(unsigned long nr)
  3442. +{
  3443. +  writefromint = 1;
  3444. +  amiga_write(nr, (unsigned long)raw_buf, trackdata, savedtrack);
  3445. +  if (!raw_write(nr, savedtrack, raw_buf, unit[nr].type->write_size)) {
  3446. +    printk ("floppy disk write protected\n");
  3447. +    writefromint = 0;
  3448. +    writepending = 0;
  3449. +  }
  3450. +}
  3451. +
  3452. +static int non_int_flush_track (unsigned long nr)
  3453. +{
  3454. +  writefromint = 0;
  3455. +  amiga_write(nr, (unsigned long)raw_buf, trackdata, savedtrack);
  3456. +  if (!raw_write(nr, savedtrack, raw_buf, unit[nr].type->write_size)) {
  3457. +    printk ("floppy disk write protected in write!\n");
  3458. +    writepending = 0;
  3459. +    return 0;
  3460. +  }
  3461. +  while (block_flag == 2)
  3462. +    sleep_on (&wait_fd_block);
  3463. +  post_write();
  3464. +  return 1;
  3465. +}
  3466. +
  3467.  static void redo_fd_request(void)
  3468.  {
  3469.      unsigned int block, track, sector;
  3470.      int device, drive, cnt;
  3471.      struct floppy_struct *floppy;
  3472.      char *data;
  3473. +    unsigned long flags;
  3474.  
  3475.      if (CURRENT && CURRENT->dev < 0) return;
  3476.  
  3477. @@ -760,6 +791,18 @@
  3478.          floppy = unit + drive;
  3479.      }
  3480.  
  3481. +    save_flags (flags);
  3482. +    cli();
  3483. +    if (drive != selected && writepending) {
  3484. +      del_timer (&flush_track_timer);
  3485. +      restore_flags (flags);
  3486. +      if (!non_int_flush_track (selected)) {
  3487. +        end_request(0);
  3488. +        goto repeat;
  3489. +      }
  3490. +    } else
  3491. +      restore_flags (flags);
  3492. +
  3493.      for (cnt = 0; cnt < 2; cnt++) {
  3494.          block = CURRENT->sector + cnt;
  3495.          if ((int)block > floppy->blocks) {
  3496. @@ -771,6 +814,18 @@
  3497.          sector = block - track * floppy->dtype->sects;
  3498.          data = CURRENT->buffer + 512 * cnt;
  3499.  
  3500. +        save_flags (flags);
  3501. +        cli();
  3502. +        if (track != savedtrack && writepending) {
  3503. +          del_timer (&flush_track_timer);
  3504. +          restore_flags (flags);
  3505. +          if (!non_int_flush_track (selected)) {
  3506. +            end_request(0);
  3507. +            goto repeat;
  3508. +          }
  3509. +        } else
  3510. +          restore_flags (flags);
  3511. +
  3512.          switch (CURRENT->cmd) {
  3513.              case READ:
  3514.              if (!motor_on (drive)) {
  3515. @@ -804,16 +859,22 @@
  3516.                  goto repeat;
  3517.              }
  3518.              copy_buffer(data, trackdata + sector * 512);
  3519. -            if (cnt == 1 || track != ((block+1)/floppy->dtype->sects)) {
  3520. -                amiga_write(drive, (unsigned long)raw_buf,
  3521. -                        trackdata, track);
  3522. -                if (!raw_write(drive, track, raw_buf,
  3523. -                           unit[drive].type->write_size)) {
  3524. -                    printk ("floppy disk write protected\n");
  3525. -                    end_request(0);
  3526. -                    goto repeat;
  3527. -                }
  3528. -            }
  3529. +            /*
  3530. +             * setup a callback to write the track buffer
  3531. +             * after a short (1 tick) delay.
  3532. +             */
  3533. +            save_flags (flags);
  3534. +            cli();
  3535. +
  3536. +            if (writepending)
  3537. +                /* reset the timer */
  3538. +                del_timer (&flush_track_timer);
  3539. +                
  3540. +            writepending = 1;
  3541. +            flush_track_timer.data = drive;
  3542. +            flush_track_timer.expires = 1;
  3543. +            add_timer (&flush_track_timer);
  3544. +            restore_flags (flags);
  3545.              break;
  3546.  
  3547.              default:
  3548. @@ -942,7 +1003,7 @@
  3549.      printk("Probing floppy drive(s):\n");
  3550.      for (drive = 0; drive < FD_MAX_UNITS; drive++) {
  3551.          fd_probe(drive);
  3552. -        if (unit[drive].type != FD_NODRIVE)
  3553. +        if (unit[drive].type->code != FD_NODRIVE)
  3554.              printk("Unit %d: %s\n", drive, unit[drive].type->name);
  3555.      }
  3556.  }
  3557. @@ -989,7 +1050,18 @@
  3558.  
  3559.  static void floppy_release(struct inode * inode, struct file * filp)
  3560.  {
  3561. +  unsigned long flags;
  3562. +
  3563.    sync_dev(inode->i_rdev);
  3564. +  save_flags (flags);
  3565. +  cli();
  3566. +  if ((inode->i_rdev & 3) == selected && writepending) {
  3567. +    del_timer (&flush_track_timer);
  3568. +    restore_flags (flags);
  3569. +    non_int_flush_track (selected);
  3570. +  } else
  3571. +    restore_flags (flags);
  3572. +  
  3573.    if (!fd_ref[inode->i_rdev & 3]--) {
  3574.      printk("floppy_release with fd_ref == 0");
  3575.      fd_ref[inode->i_rdev & 3] = 0;
  3576. @@ -1013,9 +1085,18 @@
  3577.  {
  3578.      if (block_flag)
  3579.          custom.dsklen = 0x4000;
  3580. -    block_flag = 0;
  3581.  
  3582. +  block_flag = 0;
  3583.      wake_up (&wait_fd_block);
  3584. +
  3585. +  if (writefromint) {
  3586. +    /* 
  3587. +     * if it was a write from an interrupt,
  3588. +     * we will call post_write from here
  3589. +     */
  3590. +    post_write ();
  3591. +  }
  3592. +
  3593.  }
  3594.  
  3595.  void amiga_floppy_init(void)
  3596. @@ -1043,6 +1124,12 @@
  3597.        unit[i].track = -1;
  3598.    }
  3599.  
  3600. +  flush_track_timer.next = NULL;
  3601. +  flush_track_timer.prev = NULL;
  3602. +  flush_track_timer.expires = 0;
  3603. +  flush_track_timer.data = 0;
  3604. +  flush_track_timer.function = flush_track_callback;
  3605. +  
  3606.    /* blk_size[MAJOR_NR] = floppy_sizes; */
  3607.    blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
  3608.  
  3609. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/drivers/block/amihd.c linux-0.9pl4/drivers/block/amihd.c
  3610. --- linux-0.9pl3/drivers/block/amihd.c    Sun Aug 28 17:24:18 1994
  3611. +++ linux-0.9pl4/drivers/block/amihd.c    Thu Nov 24 20:52:37 1994
  3612. @@ -18,6 +18,8 @@
  3613.   *
  3614.   *
  3615.   *  Modified 1994 for A4000/40 IDE controller support by Torsten Ebeling
  3616. + *
  3617. + *  Modified 16-Nov-1994 to add A1200 IDE controller support by Dwight Engen
  3618.   */
  3619.   
  3620.  /*
  3621. @@ -70,7 +72,11 @@
  3622.  struct hd_i_struct {
  3623.      unsigned int head,sect,cyl,wpcom,lzone,ctl;
  3624.      };
  3625. +struct hd_regs_struct {
  3626. +    unsigned char *hd_data, *hd_error, *hd_nsector, *hd_sector, *hd_lcyl,
  3627. +    *hd_hcyl, *hd_current, *hd_status, *hd_cmd; };
  3628.  static struct hd_i_struct hd_info[] = { {0,0,0,0,0,0},{0,0,0,0,0,0} };
  3629. +static struct hd_regs_struct hd_regs;
  3630.  static int NR_HD = 0;
  3631.  
  3632.  static struct hd_struct hd[MAX_HD<<6]={{0,0},};
  3633. @@ -100,7 +106,7 @@
  3634.           movew a0@,a1@+; \
  3635.           movew a0@,a1@+; \
  3636.           movew a0@,a1@+; \
  3637. -         dbra d6,1b" : : "i" (port), "g" (buf), "g" (nr) : "a0", "a1", "d6");
  3638. +         dbra d6,1b" : : "g" (port), "g" (buf), "g" (nr) : "a0", "a1", "d6");
  3639.  
  3640.  #define port_write(port, buf, nr) \
  3641.  __asm__ __volatile__ \
  3642. @@ -123,7 +129,7 @@
  3643.           movew a1@+,a0@; \
  3644.           movew a1@+,a0@; \
  3645.           movew a1@+,a0@; \
  3646. -         dbra d6,1b" : : "i" (port), "g" (buf), "g" (nr) : "a0", "a1", "d6");
  3647. +         dbra d6,1b" : : "g" (port), "g" (buf), "g" (nr) : "a0", "a1", "d6");
  3648.  
  3649.  void amiga_hd_setup(char *str, int *ints)
  3650.  {
  3651. @@ -143,7 +149,7 @@
  3652.  
  3653.  static int win_result(void)
  3654.  {
  3655. -    int i=inb_p(HD_STATUS);
  3656. +    int i=inb_p(hd_regs.hd_status);
  3657.  
  3658.      if ((i & (BUSY_STAT | READY_STAT | WRERR_STAT | SEEK_STAT | ERR_STAT))
  3659.          == (READY_STAT | SEEK_STAT)) {
  3660. @@ -152,7 +158,7 @@
  3661.      }
  3662.      printk("HD: win_result: status = 0x%02x\n",i);
  3663.      if (i&1) {
  3664. -        hd_error = inb(HD_ERROR);
  3665. +        hd_error = inb(hd_regs.hd_error);
  3666.          printk("HD: win_result: error = 0x%02x\n",hd_error);
  3667.      }    
  3668.      return 1;
  3669. @@ -168,7 +174,7 @@
  3670.      do {
  3671.          if (controller_busy() & BUSY_STAT)
  3672.              return 0;
  3673. -        outb_p(0xA0 | (drive<<4) | head, HD_CURRENT);
  3674. +        outb_p(0xA0 | (drive<<4) | head, hd_regs.hd_current);
  3675.          if (status_ok())
  3676.              return 1;
  3677.      } while (--retry);
  3678. @@ -177,7 +183,7 @@
  3679.  
  3680.  static int status_ok(void)
  3681.  {
  3682. -    unsigned char status = inb_p(HD_STATUS);
  3683. +    unsigned char status = inb_p(hd_regs.hd_status);
  3684.  
  3685.      if (status & BUSY_STAT)
  3686.          return 1;
  3687. @@ -196,7 +202,7 @@
  3688.      unsigned char status;
  3689.  
  3690.      do {
  3691. -        status = inb_p(HD_STATUS);
  3692. +        status = inb_p(hd_regs.hd_status);
  3693.      } while ((status & BUSY_STAT) && --retries);
  3694.      return status;
  3695.  }
  3696. @@ -214,14 +220,18 @@
  3697.          return;
  3698.      }
  3699.      SET_INTR(intr_addr);
  3700. -    outb(hd_info[drive].ctl,HD_CMD);
  3701. -    outb_p(hd_info[drive].wpcom>>2,HD_PRECOMP);
  3702. -    outb_p(nsect,HD_NSECTOR);
  3703. -    outb_p(sect,HD_SECTOR);
  3704. -    outb_p(cyl,HD_LCYL);
  3705. -    outb_p(cyl>>8,HD_HCYL);
  3706. -    outb_p(0xA0|(drive<<4)|head,HD_CURRENT);
  3707. -    outb_p(cmd,HD_COMMAND);
  3708. +    outb(hd_info[drive].ctl,hd_regs.hd_cmd);
  3709. +
  3710. +    /* Note hd_regs.hd_error is precomp on write, but error on read */
  3711. +    outb_p(hd_info[drive].wpcom>>2,hd_regs.hd_error);
  3712. +    outb_p(nsect,hd_regs.hd_nsector);
  3713. +    outb_p(sect,hd_regs.hd_sector);
  3714. +    outb_p(cyl,hd_regs.hd_lcyl);
  3715. +    outb_p(cyl>>8,hd_regs.hd_hcyl);
  3716. +    outb_p(0xA0|(drive<<4)|head,hd_regs.hd_current);
  3717. +
  3718. +    /* Note hd_regs.hd_status is status on read and command on write */
  3719. +    outb_p(cmd,hd_regs.hd_status);
  3720.  }
  3721.  
  3722.  static int drive_busy(void)
  3723. @@ -230,7 +240,7 @@
  3724.      unsigned char c;
  3725.  
  3726.      for (i = 0; i < 500000 ; i++) {
  3727. -        c = inb_p(HD_STATUS);
  3728. +        c = inb_p(hd_regs.hd_status);
  3729.          c &= (BUSY_STAT | READY_STAT | SEEK_STAT);
  3730.          if (c == (READY_STAT | SEEK_STAT))
  3731.              return 0;
  3732. @@ -244,12 +254,12 @@
  3733.      int    i;
  3734.  
  3735.      printk(KERN_DEBUG "HD-controller reset\n");
  3736. -    outb(4,HD_CMD);
  3737. +    outb(4,hd_regs.hd_cmd);
  3738.      for(i = 0; i < 1000; i++) nop();
  3739. -    outb(hd_info[0].ctl & 0x0f ,HD_CMD);
  3740. +    outb(hd_info[0].ctl & 0x0f ,hd_regs.hd_cmd);
  3741.      if (drive_busy())
  3742.          printk("HD-controller still busy\n");
  3743. -    if ((hd_error = inb(HD_ERROR)) != 1)
  3744. +    if ((hd_error = inb(hd_regs.hd_error)) != 1)
  3745.          printk("HD-controller reset failed: %02x\n",hd_error);
  3746.  }
  3747.  
  3748. @@ -315,7 +325,7 @@
  3749.      int retries = 100000;
  3750.  
  3751.      while (--retries > 0)
  3752. -        if (inb_p(HD_STATUS) & DRQ_STAT)
  3753. +        if (inb_p(hd_regs.hd_status) & DRQ_STAT)
  3754.              return 0;
  3755.      return -1;
  3756.  }
  3757. @@ -329,7 +339,7 @@
  3758.      int retries = 100000;
  3759.  
  3760.      do {
  3761. -        i = (unsigned) inb_p(HD_STATUS);
  3762. +        i = (unsigned) inb_p(hd_regs.hd_status);
  3763.          if (i & BUSY_STAT)
  3764.              continue;
  3765.          if ((i & STAT_MASK) != STAT_OK)
  3766. @@ -339,14 +349,14 @@
  3767.      } while (--retries > 0);
  3768.      printk("HD: read_intr: status = 0x%02x\n",i);
  3769.      if (i & ERR_STAT) {
  3770. -        hd_error = (unsigned) inb(HD_ERROR);
  3771. +        hd_error = (unsigned) inb(hd_regs.hd_error);
  3772.          printk("HD: read_intr: error = 0x%02x\n",hd_error);
  3773.      }
  3774.      bad_rw_intr();
  3775.      do_hd_request();
  3776.      return;
  3777.  ok_to_read:
  3778. -    port_read(HD_DATA,CURRENT->buffer,15);
  3779. +    port_read(hd_regs.hd_data,CURRENT->buffer,15);
  3780.      CURRENT->errors = 0;
  3781.      CURRENT->buffer += 512;
  3782.      CURRENT->sector++;
  3783. @@ -363,7 +373,7 @@
  3784.          SET_INTR(&read_intr);
  3785.          return;
  3786.      }
  3787. -    (void) inb_p(HD_STATUS);
  3788. +    (void) inb_p(hd_regs.hd_status);
  3789.  #if (HD_DELAY > 0)
  3790.      last_req = read_timer();
  3791.  #endif
  3792. @@ -377,7 +387,7 @@
  3793.      int retries = 100000;
  3794.  
  3795.      do {
  3796. -        i = (unsigned) inb_p(HD_STATUS);
  3797. +        i = (unsigned) inb_p(hd_regs.hd_status);
  3798.          if (i & BUSY_STAT)
  3799.              continue;
  3800.          if ((i & STAT_MASK) != STAT_OK)
  3801. @@ -387,7 +397,7 @@
  3802.      } while (--retries > 0);
  3803.      printk("HD: write_intr: status = 0x%02x\n",i);
  3804.      if (i & ERR_STAT) {
  3805. -        hd_error = (unsigned) inb(HD_ERROR);
  3806. +        hd_error = (unsigned) inb(hd_regs.hd_error);
  3807.          printk("HD: write_intr: error = 0x%02x\n",hd_error);
  3808.      }
  3809.      bad_rw_intr();
  3810. @@ -402,7 +412,7 @@
  3811.          end_request(1);
  3812.      if (i > 0) {
  3813.        SET_INTR(&write_intr);
  3814. -        port_write(HD_DATA,CURRENT->buffer,15);
  3815. +        port_write(hd_regs.hd_data,CURRENT->buffer,15);
  3816.      } else {
  3817.          do_hd_request();
  3818.      }
  3819. @@ -502,7 +512,7 @@
  3820.              bad_rw_intr();
  3821.              goto repeat;
  3822.          }
  3823. -        port_write(HD_DATA,CURRENT->buffer,15);
  3824. +        port_write(hd_regs.hd_data,CURRENT->buffer,15);
  3825.          return;
  3826.      }
  3827.      if (CURRENT->cmd == READ) {
  3828. @@ -614,17 +624,27 @@
  3829.   ********************************************************/
  3830.  static void hd_interrupt (struct intframe *fp, void *data)
  3831.  {
  3832. +unsigned char ch;
  3833.  void (*hd_irq_handler)(void) = DEVICE_INTR;
  3834.  
  3835. -/* Test, if this is a harddisk interrupt. MSB(0xdd2030) = 1 */
  3836. -if (inb (HD_IRQ_TEST) & 0x80)
  3837. +/* Test, if this is a harddisk interrupt. MSB = 1, hd is source of interrupt */
  3838. +if (boot_info.bi_amiga.model == AMI_4000)
  3839. +  ch = inb(HD_A4000_IRQ);
  3840. +else
  3841. +  ch = inb(HD_A1200_IRQ);
  3842. +  
  3843. +if (ch & 0x80)
  3844.    {
  3845.    DEVICE_INTR = NULL;
  3846.    timer_active &= ~(1 << HD_TIMER);
  3847.  
  3848.    if (!hd_irq_handler)
  3849. +  {
  3850.      hd_irq_handler = unexpected_hd_interrupt;
  3851. -  hd_irq_handler ();
  3852. +  }
  3853. +  hd_irq_handler();
  3854. +  if (boot_info.bi_amiga.model == AMI_1200)
  3855. +    outb(0x7c | (ch & 0x03), HD_A1200_IRQ);
  3856.  
  3857.    return;
  3858.    }
  3859. @@ -646,15 +666,33 @@
  3860.  printk ("Probing harddisk(s):\n");
  3861.  NR_HD = 0;
  3862.  
  3863. -/* Test, if it's an A4000 or an A1200 */
  3864. -if ((boot_info.bi_amiga.model != AMI_4000) && (boot_info.bi_amiga.model != AMI_1200))
  3865. -  {
  3866. +/* Test if an A4000 or an A1200 and setup the base of hd_regs acordingly */
  3867. +if (boot_info.bi_amiga.model == AMI_4000)
  3868. +{
  3869. +  hd_regs.hd_data = (unsigned char *)HD_BASE_A4000;
  3870. +}
  3871. +else if (boot_info.bi_amiga.model == AMI_1200)
  3872. +{
  3873. +  hd_regs.hd_data = (unsigned char *)HD_BASE_A1200;
  3874. +}
  3875. +else /* Not A4000 nor A1200, doesn't have a supported IDE controller */
  3876. +{
  3877.    printk ("IDE harddisk controller not present.\n");
  3878.    hd_gendisk.nr_real = NR_HD;
  3879.    return;
  3880. -  }
  3881. +}
  3882.  
  3883. -outb (IDE_DISABLE_IRQ, HD_CMD);     /* Disable HD-interrupt */
  3884. +/* Now set the rest of hd_regs struct */
  3885. +hd_regs.hd_error    = hd_regs.hd_data + HD_ERROR;
  3886. +hd_regs.hd_nsector    = hd_regs.hd_data + HD_NSECTOR;
  3887. +hd_regs.hd_sector    = hd_regs.hd_data + HD_SECTOR;
  3888. +hd_regs.hd_lcyl        = hd_regs.hd_data + HD_LCYL;
  3889. +hd_regs.hd_hcyl        = hd_regs.hd_data + HD_HCYL;
  3890. +hd_regs.hd_current    = hd_regs.hd_data + HD_CURRENT;
  3891. +hd_regs.hd_status    = hd_regs.hd_data + HD_STATUS;
  3892. +hd_regs.hd_cmd        = hd_regs.hd_data + HD_CMD;
  3893. +
  3894. +outb (IDE_DISABLE_IRQ, hd_regs.hd_cmd);     /* Disable HD-interrupt */
  3895.  cli ();                             /* Disable interrupts   */
  3896.  
  3897.  for (drive=0; drive<2; drive++)
  3898. @@ -667,20 +705,21 @@
  3899.      }
  3900.  
  3901.    /* select drive */
  3902. -  outb_p ((unsigned char) (0xA0 | (drive<<4)), HD_CURRENT);
  3903. +  outb_p ((unsigned char) (0xA0 | (drive<<4)), hd_regs.hd_current);
  3904.  
  3905.    /* Set identify command */
  3906. -  outb_p (WIN_IDENTIFY, HD_COMMAND);
  3907. +  /* Note hd_regs.hd_status is status on read and command on write */
  3908. +  outb_p (WIN_IDENTIFY, hd_regs.hd_status);
  3909.  
  3910.    drive_found = 0;
  3911.    /* Test, if ready to read */
  3912.    for (i=0; i<HD_ID_RETRIES; i++)
  3913.      {
  3914. -    if ((inb_p(HD_STATUS) & (DRQ_STAT|READY_STAT)) == (DRQ_STAT|READY_STAT)) /* ++hn: Detect Seagate drives properly */
  3915. +    if ((inb_p(hd_regs.hd_status) & (DRQ_STAT|READY_STAT)) == (DRQ_STAT|READY_STAT)) /* ++hn: Detect Seagate drives properly */
  3916.        {
  3917.        drive_found = 1;
  3918.  #ifdef DEBUG
  3919. -      printk("hd%d: WIN_IDENTIFY: status = 0x%hx\n", drive, inb_p(HD_STATUS));
  3920. +      printk("hd%d: WIN_IDENTIFY: status = 0x%hx\n", drive, inb_p(hd_regs.hd_status));
  3921.  #endif
  3922.        break;
  3923.        }
  3924. @@ -688,7 +727,7 @@
  3925.    
  3926.    if (drive_found)
  3927.      {
  3928. -    port_read (HD_DATA, Identify, 15);
  3929. +    port_read (hd_regs.hd_data, Identify, 15);
  3930.      for (i=0; i<256; i++)
  3931.        /* We need to swap MSB and LSB */
  3932.        Identify [i] = (Identify [i] << 8) | (Identify [i] >> 8);
  3933. @@ -711,6 +750,7 @@
  3934.      printk ("hd%c not found.\n", (char)drive+'a'); /* ++hn: use hda/hdb naming for the user-messages */
  3935.    }
  3936.  sti ();                             /* Enable interrupts */
  3937. +
  3938.  
  3939.  /* Add the interrupt handler */
  3940.  if (NR_HD)
  3941. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/drivers/block/ataflop.c linux-0.9pl4/drivers/block/ataflop.c
  3942. --- linux-0.9pl3/drivers/block/ataflop.c    Sun Aug 14 10:30:45 1994
  3943. +++ linux-0.9pl4/drivers/block/ataflop.c    Thu Nov 24 21:13:32 1994
  3944. @@ -2,8 +2,40 @@
  3945.   *  linux/kernel/blk_drv/floppy.c
  3946.   *
  3947.   *  Copyright (C) 1993  Greg Harp
  3948. - *  Atari Support by Björn Brauel
  3949. + *  Atari Support by Bjoern Brauel, Roman Hodek
  3950.   *
  3951. + *  Big cleanup Sep 11..14 1994 Roman Hodek:
  3952. + *   - Driver now works interrupt driven
  3953. + *   - Support for two drives; should work, but I cannot test that :-(
  3954. + *   - Reading is done in whole tracks and buffered to speed up things
  3955. + *   - Disk change detection and drive deselecting after motor-off
  3956. + *     similar to TOS
  3957. + *   - Autodetection of disk format (DD/HD); untested yet, because I
  3958. + *     don't have an HD drive :-(
  3959. + *
  3960. + *  Fixes Nov 13 1994 Martin Schaller:
  3961. + *   - Autodetection works now
  3962. + *   - Support for 5 1/4" disks
  3963. + *   - Removed drive type (unknown on atari)
  3964. + *   - Do seeks with 8 Mhz
  3965. + *
  3966. + *  Things left to do:
  3967. + *   - Formatting
  3968. + *   - Maybe a better strategy for disk change detection (does anyone
  3969. + *     know one?)
  3970. + *   - In case of disk errors, don't give up immediatly but retry
  3971. + *     several times
  3972. + *   - There are some strange problems left: The strangest one is
  3973. + *     that, at least on my TT (4+4MB), the first 2 Bytes of the last
  3974. + *     page of the TT-Ram (!) change their contents (some bits get
  3975. + *     set) while a floppy DMA is going on. But there are no accesses
  3976. + *     to these memory locations from the kernel... (I tested that by
  3977. + *     making the page read-only). I cannot explain what's going on...
  3978. + *   - Sometimes the drive-change-detection stops to work. The
  3979. + *     function is still called, but the WP bit always reads as 0...
  3980. + *     Maybe a problem with the status reg mode or a timing problem.
  3981. + *     Note 10/12/94: The change detection now seems to work reliably.
  3982. + *     There is no proof, but I've seen no hang for a long time...
  3983.   */
  3984.  
  3985.  #include <linux/config.h>
  3986. @@ -20,351 +52,950 @@
  3987.  #include <linux/interrupt.h>
  3988.  #include <linux/mm.h>
  3989.  #include <asm/system.h>
  3990. +#include <asm/bitops.h>
  3991.  
  3992.  #include <linux/atarihw.h>
  3993.  #include <linux/atariints.h>
  3994. +#include <linux/atari_stdma.h>
  3995.  
  3996.  #define MAJOR_NR FLOPPY_MAJOR
  3997.  #include "blk.h"
  3998.  
  3999. -#undef __notneeded__
  4000.  
  4001. -/*
  4002. - *  Defines
  4003. +/* Note: FD_MAX_UNITS could be redefined to 2 for the Atari (with
  4004. + * little additional rework in this file). But I'm not yet sure if
  4005. + * some other code depends on the number of floppies... (It is defined
  4006. + * in a public header!)
  4007.   */
  4008. -#define MAX_SECTORS    22
  4009. -#define RAW_BUF     900000
  4010. +#if 0
  4011. +#undef FD_MAX_UNITS
  4012. +#define    FD_MAX_UNITS    2
  4013. +#endif
  4014.  
  4015. -/*
  4016. - *  Error codes
  4017. - */
  4018. -#define FD_OK        0    /* operation succeeded */
  4019. -#define FD_ERROR    -1    /* general error (seek, read, write, etc) */
  4020. -#define FD_NOUNIT    1    /* unit does not exist */
  4021. -#define FD_UNITBUSY    2    /* unit already active */
  4022. -#define FD_NOTACTIVE    3    /* unit is not active */
  4023. -#define FD_NOTREADY    4    /* unit is not ready (motor not on/no disk) */
  4024. +#define TRACKBUFFER 1
  4025. +#undef DEBUG
  4026.  
  4027. -/*
  4028. - *  Floppy ID values
  4029. - */
  4030. -#define FD_NODRIVE    0x00000000  /* response when no unit is present */
  4031. -#define FD_HD_3     0xaaaaaaaa  /* high-density 3.5'' (1760K) drive */
  4032. -#define FD_DD_3     0xbbbbbbbb  /* high-density 3.5'' (880K) drive */
  4033. +/* Disk types: DD or HD */
  4034. +static struct atari_disk_type {
  4035. +    const char    *name;
  4036. +    unsigned    spt;        /* sectors per track */
  4037. +    unsigned    blocks;        /* total number of blocks */
  4038. +    unsigned    fdc_speed;    /* fdc_speed setting */
  4039. +    unsigned     stretch;    /* track doubling ? */
  4040. +} disk_type[] = {
  4041. +    { "d360",  9, 720, 0, 0},    /* 360kB diskette */
  4042. +    { "h1220",15,2400, 3, 0},    /* 1.2MB diskette */
  4043. +    { "D360",  9, 720, 0, 1},    /* 360kb in 720kb drive */
  4044. +    { "D720",  9,1440, 0, 0},    /* 720kb diskette (DD) */    
  4045. +/* the following 2 are only aliases on the atari, since we can't read/write 
  4046. +   with 300kbps */
  4047. +    { "h360",  9, 720, 0, 1},    /* 360kb in 1.2MB drive */
  4048. +    { "h720",  9,1440, 0, 0},    /* 720kb in 1.2MB drive */
  4049. +    { "H1440",18,2880, 3, 0}    /* 1.44MB diskette (HD) */
  4050. +};
  4051.  
  4052. +#define    NUM_DISK_TYPES (sizeof(disk_type)/sizeof(*disk_type))
  4053.  
  4054. -/* Atari: Auto probing not implemented yet! If CONFIG_FLOPPY_DD_ONLY
  4055. - * is not defined, all accesses are done for a HD disk.
  4056. +/* current info on each unit */
  4057. +static struct atari_floppy_struct {
  4058. +    int connected;                /* !=0 : drive is connected */
  4059. +    int autoprobe;                /* !=0 : do autoprobe        */
  4060. +
  4061. +    struct atari_disk_type    *disktype;    /* current type of disk */
  4062. +
  4063. +             int            track;        /* current head position or -1
  4064. +                                         * if unknown */
  4065. +    unsigned int            steprate;    /* steprate setting */
  4066. +    unsigned int            wpstat;        /* current state of WP signal
  4067. +                                         * (for disk change detection) */
  4068. +} unit[FD_MAX_UNITS];
  4069. +
  4070. +
  4071. +#define FDC_READ(reg) ({                        \
  4072. +    /* unsigned long __flags; */                \
  4073. +    unsigned short __val;                        \
  4074. +    /* save_flags(__flags); cli(); */            \
  4075. +    dma_wd.dma_mode_status = 0x80 | (reg);        \
  4076. +    udelay(40);                                    \
  4077. +    __val = dma_wd.fdc_acces_seccount;            \
  4078. +    /* restore_flags(__flags); */                \
  4079. +    __val & 0xff;                                \
  4080. +})
  4081. +
  4082. +#define FDC_WRITE(reg,val)                        \
  4083. +    do {                                        \
  4084. +        /* unsigned long __flags; */            \
  4085. +        /* save_flags(__flags); cli(); */        \
  4086. +        dma_wd.dma_mode_status = 0x80 | (reg);    \
  4087. +        udelay(40);                                \
  4088. +        dma_wd.fdc_acces_seccount = (val);        \
  4089. +        /* restore_flags(__flags); */            \
  4090. +    } while(0)
  4091. +
  4092. +
  4093. +/* Buffering variables:
  4094. + * First, there is a DMA buffer in ST-RAM that is used for floppy DMA
  4095. + * operations. Second, a track buffer is used to cache a whole track
  4096. + * of the disk to save read operations. These are two seperate buffers
  4097. + * because that allows write operations without clearing the track buffer.
  4098.   */
  4099.  
  4100. -/* For Atari, fields rdsz, wrsz, sm, pc1, pc2, sd, st, st unused */
  4101. +#define    MAX_SECTORS    22
  4102.  
  4103. -static struct fd_drive_type drive_types[] = {
  4104. -/*  code    name       tr he   rdsz   wrsz sm pc1 pc2    sd     st    st*/
  4105. - { FD_HD_3,    "HD 3.5", 160, 2, 25000, 25000, 2, 80,161, 3000, 18000, 1000},
  4106. - { FD_DD_3,    "DD 3.5", 160, 2, 25000, 25000, 1, 80,161, 3000, 18000, 1000},
  4107. - { FD_NODRIVE, "No Drive",  0, 0,     0,     0, 0,  0,  0,    0,     0,    0}
  4108. -};
  4109. -#ifdef __notneeded__
  4110. -static int num_dr_types = sizeof(drive_types) / sizeof(drive_types[0]);
  4111. -#endif
  4112. +unsigned char *DMABuffer;              /* buffer for writes */
  4113. +static unsigned long PhysDMABuffer;   /* physical address */
  4114.  
  4115. -static struct fd_data_type data_types[] = {
  4116. -  { "Atari", 9 }
  4117. -};
  4118. -#ifdef __notneeded__
  4119. -static int num_da_types = sizeof(data_types) / sizeof(data_types[0]);
  4120. +#ifdef TRACKBUFFER
  4121. +unsigned char *TrackBuffer;              /* buffer for reads */
  4122. +static unsigned long PhysTrackBuffer; /* physical address */
  4123. +static int BufferDrive, BufferSide, BufferTrack;
  4124. +static int error_drive, error_side, error_track;
  4125. +
  4126. +#define    SECTOR_BUFFER(sec)    (TrackBuffer + ((sec)-1)*512)
  4127. +#define    IS_BUFFERED(drive,side,track) \
  4128. +    (BufferDrive == (drive) && BufferSide == (side) && BufferTrack == (track))
  4129.  #endif
  4130.  
  4131. -
  4132. -/* current info on each unit */
  4133. -static struct floppy_struct unit[FD_MAX_UNITS];
  4134. -
  4135. -/* track buffer */
  4136. -static int savedtrack = -1;
  4137. -unsigned char *trackdata; /* allocated by atari_stram_alloc */
  4138. -
  4139.  /*
  4140.   * These are global variables, as that's the easiest way to give
  4141.   * information to interrupts. They are the data used for the current
  4142.   * request.
  4143.   */
  4144. -static char block_flag = 0;
  4145. -static int selected = 0;
  4146. -static struct wait_queue *wait_on_floppy_select = NULL;
  4147. -static struct wait_queue *wait_fd_block = NULL;
  4148. +static int SelectedDrive = 0;
  4149. +static int ReqCmd, ReqBlock;
  4150. +static int ReqSide, ReqTrack, ReqSector, ReqCnt;
  4151. +static int HeadSettleFlag = 0;
  4152. +static unsigned char *ReqData, *ReqBuffer;
  4153. +static int MotorOn = 0, MotorOffTrys;
  4154.  
  4155.  /* Synchronization of FDC access. */
  4156. -#ifdef __notneeded__
  4157.  static volatile int fdc_busy = 0;
  4158.  static struct wait_queue *fdc_wait = NULL;
  4159. -static struct wait_queue *motor_wait = NULL;
  4160. +
  4161. +static unsigned int changed_floppies = 0xff, fake_change = 0;
  4162. +#define    CHECK_CHANGE_DELAY    HZ/2
  4163. +
  4164. +#define    FD_MOTOR_OFF_DELAY    (3*HZ)
  4165. +#define    FD_MOTOR_OFF_MAXTRY    (10*20)
  4166. +
  4167. +#define    START_MOTOR_OFF_TIMER(delay)            \
  4168. +    do {                                        \
  4169. +        motor_off_timer.expires = (delay);        \
  4170. +        add_timer( &motor_off_timer );            \
  4171. +        MotorOffTrys = 0;                        \
  4172. +    } while(0)
  4173. +
  4174. +#define    START_CHECK_CHANGE_TIMER(delay)                            \
  4175. +    do {                                                        \
  4176. +        timer_table[FLOPPY_TIMER].expires = jiffies + (delay);    \
  4177. +        timer_active |= (1 << FLOPPY_TIMER);                    \
  4178. +    } while(0)
  4179. +
  4180. +
  4181. +/*
  4182. + * The driver is trying to determine the correct media format
  4183. + * while Probing is set. fd_rwsec_done() clears it after a
  4184. + * successful access.
  4185. + */
  4186. +static int Probing = 0;
  4187. +
  4188. +/* This flag is set when a dummy seek is necesary to make the WP
  4189. + * status bit accessible.
  4190. + */
  4191. +static int NeedSeek = 0;
  4192. +
  4193. +
  4194. +#ifdef DEBUG
  4195. +#define DPRINT(a)    printk a
  4196. +#else
  4197. +#define DPRINT(a)
  4198.  #endif
  4199.  
  4200.  #if 0
  4201. -static unsigned int changed_floppies = 0;
  4202. +
  4203. +unsigned long RCont = 0;
  4204. +
  4205. +#define TEST_PAGE(str,adr)                                            \
  4206. +    do {                                                            \
  4207. +        if (*(unsigned long *)0xc03ff000 != RCont) {                \
  4208. +            printk("*0xc03ff000 = %08lx mem_map[]=%d\n",               \
  4209. +                   (RCont = *(unsigned long *)0xc03ff000),            \
  4210. +                   mem_map[MAP_NR(0xc03ff000)] );                    \
  4211. +            printk("%s ",(str));                                    \
  4212. +            printk("%08lx\n",(unsigned long)(adr));                    \
  4213. +        }                                                            \
  4214. +    } while(0)
  4215. +
  4216. +#else
  4217. +
  4218. +#define TEST_PAGE(str,adr) do {} while(0)
  4219. +
  4220.  #endif
  4221.  
  4222. -/*======================================================================
  4223. -  Select the side to use for a particular drive.
  4224. -  The drive must have been calibrated at some point before this.
  4225. -  The drive must also be active and the motor must be running.
  4226. -======================================================================*/
  4227. -#ifdef __notneeded__
  4228. -static void fd_select_side(int drive, int side)
  4229. -{
  4230. -  unsigned long flags;
  4231. +/***************************** Prototypes *****************************/
  4232. +
  4233. +static void fd_select_side( int side );
  4234. +static void fd_select_drive( int drive );
  4235. +static void fd_deselect( void );
  4236. +static void fd_motor_off_timer( unsigned long dummy );
  4237. +static void check_change( void );
  4238. +static __inline__ void set_head_settle_flag( void );
  4239. +static __inline__ int get_head_settle_flag( void );
  4240. +static void floppy_irq( struct intframe *fp, void *data );
  4241. +static void do_fd_action( int drive );
  4242. +static void fd_calibrate( void );
  4243. +static void fd_calibrate_done( int status );
  4244. +static void fd_seek( void );
  4245. +static void fd_seek_done( int status );
  4246. +static void fd_rwsec( void );
  4247. +#ifdef TRACKBUFFER
  4248. +static void fd_readtrack_check( unsigned long dummy );
  4249. +#endif
  4250. +static void fd_rwsec_done( int status );
  4251. +static void finish_fdc( void );
  4252. +static void floppy_off( unsigned int nr);
  4253. +static __inline__ void copy_buffer( void *from, void *to);
  4254. +static void setup_req_params( int drive );
  4255. +static void redo_fd_request( void);
  4256. +static int fd_ioctl( struct inode *inode, struct file *filp, unsigned int
  4257. +                     cmd, unsigned long param);
  4258. +static void fd_probe( int drive );
  4259. +static int fd_test_drive_present( int drive );
  4260. +static void config_types( void );
  4261. +static int floppy_open( struct inode *inode, struct file *filp );
  4262. +static void floppy_release( struct inode * inode, struct file * filp );
  4263. +
  4264. +/************************* End of Prototypes **************************/
  4265. +
  4266. +static struct timer_list motor_off_timer =
  4267. +                         { NULL, NULL, 0, 0, fd_motor_off_timer };
  4268. +#ifdef TRACKBUFFER
  4269. +static struct timer_list readtrack_timer =
  4270. +                         { NULL, NULL, 0, 0, fd_readtrack_check };
  4271. +#endif
  4272. +
  4273. +
  4274. +
  4275. +
  4276. +/* Select the side to use. */
  4277. +
  4278. +static void fd_select_side( int side )
  4279. +
  4280. +{    unsigned long flags;
  4281.  
  4282.    save_flags(flags);
  4283.    cli();
  4284.    
  4285. -  if(side==0)
  4286. -   {
  4287. -    sound_ym.rd_data_reg_sel=14; /* Select PSG Port A */
  4288. -    sound_ym.wd_data = sound_ym.rd_data_reg_sel | 0x01;
  4289. -   }
  4290. -  else
  4291. -   {
  4292. -    sound_ym.rd_data_reg_sel=14; /* Select PSG Port A */
  4293. -    sound_ym.wd_data = sound_ym.rd_data_reg_sel & 0xfe;
  4294. -   }
  4295. +    sound_ym.rd_data_reg_sel = 14; /* Select PSG Port A */
  4296. +    sound_ym.wd_data = (side == 0) ? sound_ym.rd_data_reg_sel | 0|01 :
  4297. +                                     sound_ym.rd_data_reg_sel & 0xfe;
  4298.  
  4299.     restore_flags(flags);
  4300.  }
  4301. -#endif
  4302.  
  4303.  
  4304. -#ifdef __notneeded__
  4305. -static struct timer_list motor_on_timer;
  4306. -static struct timer_list motor_off_timer[FD_MAX_UNITS];
  4307. -static int on_attempts;
  4308. -#endif
  4309. +/* Select a drive, update the FDC's track register and set the correct
  4310. + * clock speed for this disk's type.
  4311. + */
  4312. +
  4313. +static void fd_select_drive( int drive )
  4314.  
  4315. -static void fd_select (int drive, int side)
  4316.  {
  4317.    unsigned long flags;
  4318.    unsigned char tmp;
  4319.    
  4320. -  if (drive == selected)
  4321. +    if (drive == SelectedDrive)
  4322.        return;
  4323. -  selected = drive;
  4324.  
  4325.    save_flags(flags);
  4326.    cli();
  4327. -
  4328. -  if (side == 0)
  4329. -   {
  4330. -    sound_ym.rd_data_reg_sel=14;    /* Select PSG Port A */
  4331. +    sound_ym.rd_data_reg_sel = 14; /* Select PSG Port A */
  4332.      tmp = sound_ym.rd_data_reg_sel;
  4333. -    sound_ym.wd_data = (tmp & ~2) | 1;    /* Select Side 0 and Drive A */
  4334. -   }
  4335. -  else
  4336. -   {
  4337. +    sound_ym.wd_data = (tmp | DSKDRVNONE) & ~(drive == 0 ? DSKDRV0 : DSKDRV1);
  4338. +    restore_flags(flags);
  4339. +
  4340. +    /* restore track register to saved value */
  4341. +    FDC_WRITE( FDCREG_TRACK, unit[drive].track );
  4342. +    udelay(40);
  4343. +
  4344. +    /* select 8/16 MHz */
  4345. +    if (unit[drive].disktype)
  4346. +        dma_wd.fdc_speed = unit[drive].disktype->fdc_speed;
  4347. +    
  4348. +    SelectedDrive = drive;
  4349. +}
  4350. +
  4351. +
  4352. +/* Deselect both drives. */
  4353. +
  4354. +static void fd_deselect( void )
  4355. +
  4356. +{    unsigned long flags;
  4357. +
  4358. +    save_flags(flags);
  4359. +    cli();
  4360.      sound_ym.rd_data_reg_sel=14;    /* Select PSG Port A */
  4361. -    tmp = sound_ym.rd_data_reg_sel;
  4362. -    sound_ym.wd_data = tmp & ~3;    /* Select Side 1 and Drive A */
  4363. +    sound_ym.wd_data = sound_ym.rd_data_reg_sel | 7; /* no drives selected */
  4364. +    restore_flags(flags);
  4365. +
  4366. +    SelectedDrive = -1;
  4367. +}
  4368. +
  4369. +
  4370. +/* This timer function deselects the drives when the FDC switched the
  4371. + * motor off. The deselection cannot happen earlier because the FDC
  4372. + * counts the index signals, which arrive only if one drive is selected.
  4373. + */
  4374. +
  4375. +static void fd_motor_off_timer( unsigned long dummy )
  4376. +
  4377. +{    unsigned long flags;
  4378. +    unsigned char status;
  4379. +    int              delay;
  4380. +
  4381. +    del_timer( &motor_off_timer );
  4382. +    
  4383. +    if (SelectedDrive < 0)
  4384. +        /* no drive selected, needn't deselect anyone */
  4385. +        return;
  4386. +
  4387. +    save_flags(flags);
  4388. +    cli();
  4389. +    
  4390. +    if (stdma_islocked())
  4391. +        goto retry;
  4392. +
  4393. +    status = FDC_READ( FDCREG_STATUS );
  4394. +
  4395. +    if (!(status & 0x80)) {
  4396. +        /* motor already turned off by FDC -> deselect drives */
  4397. +        fd_deselect();
  4398. +        restore_flags(flags);
  4399. +        MotorOn = 0;
  4400. +        return;
  4401.     }
  4402. +    /* not yet off, try again */
  4403.  
  4404. +  retry:
  4405.    restore_flags(flags);
  4406. +    /* Test again later; if tested too often, it seems there is no disk
  4407. +     * in the drive and the FDC will leave the motor on forever (or,
  4408. +     * at least until a disk is inserted). So we'll test only twice
  4409. +     * per second from then on...
  4410. +     */
  4411. +    delay = (MotorOffTrys < FD_MOTOR_OFF_MAXTRY) ?
  4412. +                (++MotorOffTrys, HZ/20) : HZ/2;
  4413. +    START_MOTOR_OFF_TIMER( delay );
  4414.  }
  4415.  
  4416. -static void fd_deselect (int drive)
  4417. -{
  4418. +
  4419. +/* This function is repeatedly called to detect disk changes (as good
  4420. + * as possible) and keep track of the current state of the write protection.
  4421. + */
  4422. +
  4423. +static void check_change( void )
  4424. +
  4425. +{    static int    drive = 0;
  4426. +
  4427.    unsigned long flags;
  4428. +    unsigned char old_porta;
  4429. +    int              stat;
  4430.  
  4431. -  if (drive != selected)
  4432. -      return;
  4433. +    if (++drive > 1 || !unit[drive].connected)
  4434. +        drive = 0;
  4435. +
  4436. +    if (!stdma_islocked()) {
  4437.  
  4438.    save_flags(flags);
  4439.    cli();
  4440. -  sound_ym.rd_data_reg_sel=14; /* Select PSG Port A */
  4441. -  sound_ym.wd_data = sound_ym.rd_data_reg_sel | 7; /* no drives selected */
  4442. +        TEST_PAGE("check change timer",0);
  4443. +        sound_ym.rd_data_reg_sel = 14;
  4444. +        old_porta = sound_ym.rd_data_reg_sel;
  4445. +        sound_ym.wd_data = (old_porta | DSKDRVNONE) &
  4446. +                           ~(drive == 0 ? DSKDRV0 : DSKDRV1);
  4447. +        stat = !!(FDC_READ( FDCREG_STATUS ) & FDCSTAT_WPROT);
  4448. +        sound_ym.wd_data = old_porta;
  4449.    restore_flags(flags);
  4450.  
  4451. -  selected=-1;
  4452. +        if (stat != unit[drive].wpstat) {
  4453. +            DPRINT(( "wpstat[%d] = %d\n", drive, stat ));
  4454. +            unit[drive].wpstat = stat;
  4455. +            set_bit (drive, &changed_floppies);
  4456. +        }
  4457. +    }
  4458. +    
  4459. +    START_CHECK_CHANGE_TIMER( CHECK_CHANGE_DELAY );
  4460.  }
  4461.  
  4462. -static void fd_nobusy(void)
  4463. -{
  4464. - unsigned char fd_status;
  4465.   
  4466. - do
  4467. -   fd_status = mfp.par_dt_reg & 0x20;
  4468. - while(fd_status != 0);
  4469. +/* Handling of the Head Settling Flag: This flag should be set after each
  4470. + * seek operation, because we dont't use seeks with verify.
  4471. + */
  4472.  
  4473. +static __inline__ void set_head_settle_flag( void )
  4474. +
  4475. +{
  4476. +    HeadSettleFlag = FDCCMDADD_E;
  4477.  }
  4478.  
  4479. -/*======================================================================
  4480. -  Seek the drive to track 0.
  4481. -  The drive must be active and the motor must be running.
  4482. -  Returns standard floppy error code.
  4483. -======================================================================*/
  4484. -#ifdef __notneeded__
  4485. -static int fd_calibrate(int drive)
  4486. +static __inline__ int get_head_settle_flag( void )
  4487. +
  4488.  {
  4489. +    int    tmp = HeadSettleFlag;
  4490. +    HeadSettleFlag = 0;
  4491. +    return( tmp );
  4492. +}
  4493.  
  4494. -  fd_select(drive,0);
  4495. -  dma_wd.dma_mode_status=FDCSELREG_STP;
  4496. -  dma_wd.fdc_acces_seccount=FDCCMD_RESTORE | FDCCMDADD_V ;
  4497.    
  4498. -  fd_nobusy();
  4499. -  fd_deselect(drive);
  4500.    
  4501. -    return 1;
  4502. +
  4503. +/* General Interrupt Handling */
  4504. +
  4505. +static void (*FloppyIRQHandler)( int status ) = NULL;
  4506. +
  4507. +static void floppy_irq( struct intframe *fp, void *data )
  4508. +
  4509. +{
  4510. +    unsigned char status;
  4511. +    void (*handler)( int );
  4512. +
  4513. +    handler = FloppyIRQHandler;
  4514. +    FloppyIRQHandler = NULL;
  4515. +
  4516. +    if (handler) {
  4517. +        nop();
  4518. +        status = FDC_READ( FDCREG_STATUS );
  4519. +        DPRINT(("FDC irq, status = %02x handler = %08lx\n",status,(unsigned long)handler));
  4520. +        udelay(40);
  4521. +        handler( status );
  4522. +    }
  4523. +    else {
  4524. +        DPRINT(("FDC irq, no handler\n"));
  4525. +    }
  4526.  }
  4527. +
  4528. +#define    SET_IRQ_HANDLER(proc) do { FloppyIRQHandler = (proc); } while(0)
  4529. +
  4530. +
  4531. +/* do_fd_action() is the general procedure for a fd request: All
  4532. + * required parameter settings (drive select, side select, track
  4533. + * position) are checked and set if needed. For each of these
  4534. + * parameters and the actual reading or writing exist two functions:
  4535. + * one that starts the setting (or skips it if possible) and one
  4536. + * callback for the "done" interrupt. Each done func calls the next
  4537. + * set function to propagate the request down to fd_rwsec_done().
  4538. + */
  4539. +
  4540. +static void do_fd_action( int drive )
  4541. +
  4542. +{
  4543. +    TEST_PAGE("do_fd_action",drive);
  4544. +    DPRINT(("do_fd_action\n"));
  4545. +    
  4546. +#ifdef TRACKBUFFER
  4547. +  repeat:
  4548. +
  4549. +    if (IS_BUFFERED( drive, ReqSide, ReqTrack )) {
  4550. +        if (ReqCmd == READ) {
  4551. +            copy_buffer( SECTOR_BUFFER(ReqSector), ReqData );
  4552. +            if (++ReqCnt < 2) {
  4553. +                /* read next sector */
  4554. +                setup_req_params( drive );
  4555. +                goto repeat;
  4556. +            }
  4557. +            else {
  4558. +                /* all sectors finished */
  4559. +                end_request( 1 );
  4560. +                redo_fd_request();
  4561. +                return;
  4562. +            }
  4563. +        }
  4564. +        else {
  4565. +            /* cmd == WRITE, pay attention to track buffer
  4566. +             * consistency! */
  4567. +            copy_buffer( ReqData, SECTOR_BUFFER(ReqSector) );
  4568. +        }
  4569. +    }
  4570.  #endif
  4571.  
  4572. -/*======================================================================
  4573. -  Seek the drive to the requested cylinder.
  4574. -  The drive must have been calibrated at some point before this.
  4575. -  The drive must also be active and the motor must be running.
  4576. -======================================================================*/
  4577. -static int fd_seek(unsigned short drive, unsigned short track)
  4578. -{
  4579. -  dma_wd.dma_mode_status=FDCSELREG_DTA;
  4580. -  nop();
  4581. -  dma_wd.fdc_acces_seccount=track;
  4582. -  udelay (1);
  4583. -  dma_wd.dma_mode_status=FDCSELREG_STP;
  4584. -  nop();
  4585. -  dma_wd.fdc_acces_seccount=FDCCMD_SEEK | FDCCMDADD_V ;
  4586. -  udelay (1);
  4587. -  fd_nobusy();
  4588. +    if (SelectedDrive != drive)
  4589. +        fd_select_drive( drive );
  4590.      
  4591. -    return 1;
  4592. +    if (unit[drive].track == -1)
  4593. +        fd_calibrate();
  4594. +    else if (unit[drive].track != ReqTrack << unit[drive].disktype->stretch)
  4595. +        fd_seek();
  4596. +    else
  4597. +        fd_rwsec();
  4598.  }
  4599.  
  4600.  
  4601. -struct header {
  4602. -    unsigned char magic;
  4603. -    unsigned char track;
  4604. -    unsigned char sect;
  4605. -    unsigned char ord;
  4606. -    unsigned char labels[16];
  4607. -    unsigned long hdrchk;
  4608. -    unsigned long datachk;
  4609. -};
  4610. +/* Seek to track 0 if the current track is unknown */
  4611. +
  4612. +static void fd_calibrate( void )
  4613. +
  4614. +{
  4615. +    TEST_PAGE("fd_calibrate",0);
  4616. +    if (unit[SelectedDrive].track >= 0) {
  4617. +        fd_calibrate_done( 0 );
  4618. +        return;
  4619. +    }
  4620. +
  4621. +    dma_wd.fdc_speed = 0;     /* always seek with 8 Mhz */;
  4622. +    DPRINT(("fd_calibrate\n"));
  4623. +    SET_IRQ_HANDLER( fd_calibrate_done );
  4624. +    /* we can't verify, since the speed may be incorrect */
  4625. +    FDC_WRITE( FDCREG_CMD, FDCCMD_RESTORE | unit[SelectedDrive].steprate );
  4626. +
  4627. +    NeedSeek = 1;
  4628. +    MotorOn = 1;
  4629. +    /* wait for IRQ */
  4630. +}
  4631.  
  4632.  
  4633. +static void fd_calibrate_done( int status )
  4634.  
  4635. -/*==========================================================================
  4636. -  atari_write converts track/labels data to raw track data
  4637. -==========================================================================*/
  4638. -static void atari_write(int dr, unsigned short tr, unsigned short sec)
  4639.  {
  4640. -  unsigned long phys_secbuf,flags;
  4641. +    TEST_PAGE("calibrate_done",0);
  4642. +    DPRINT(("fd_calibrate_done()\n"));
  4643.      
  4644. -  sec=sec+1;
  4645. +    /* set the correct speed now */
  4646. +    dma_wd.fdc_speed = unit[SelectedDrive].disktype->fdc_speed;
  4647. +    if (status & FDCSTAT_RECNF) {
  4648. +        printk( "fd%d: restore failed\n", SelectedDrive );
  4649. +        end_request( 0 );
  4650. +        redo_fd_request();
  4651. +    }
  4652. +    else {
  4653. +        unit[SelectedDrive].track = 0;
  4654. +        fd_seek();
  4655. +    }
  4656. +}
  4657.    
  4658. -  phys_secbuf = (unsigned long) trackdata;
  4659.    
  4660. -  save_flags(flags);  
  4661. -  cli();
  4662. +/* Seek the drive to the requested track. The drive must have been
  4663. + * calibrated at some point before this.
  4664. + */
  4665.    
  4666. -  fd_select (dr, tr & 1);
  4667. +static void fd_seek( void )
  4668.    
  4669. -  tr=tr/2;
  4670. +{
  4671. +    TEST_PAGE("fd_seek",0);
  4672. +    if (unit[SelectedDrive].track == ReqTrack << 
  4673. +        unit[SelectedDrive].disktype->stretch) {
  4674. +        fd_seek_done( 0 );
  4675. +        return;
  4676. +    }
  4677.  
  4678. -  /* Setup head pos. */
  4679. -  fd_seek(dr,tr);
  4680. +     dma_wd.fdc_speed = 0;    /* always seek witch 8 Mhz */
  4681.  
  4682. +    DPRINT(("fd_seek() to track %d\n",ReqTrack));
  4683. +    FDC_WRITE( FDCREG_DATA, ReqTrack << 
  4684. +        unit[SelectedDrive].disktype->stretch);
  4685. +    udelay(40);
  4686. +    SET_IRQ_HANDLER( fd_seek_done );
  4687. +    FDC_WRITE( FDCREG_CMD, FDCCMD_SEEK | unit[SelectedDrive].steprate );
  4688. +
  4689. +    MotorOn = 1;
  4690. +    set_head_settle_flag();
  4691. +    /* wait for IRQ */
  4692. +}
  4693.  
  4694. -  /* Setup DMA */
  4695. -  dma_wd.dma_lo=(unsigned char)phys_secbuf;
  4696. -  phys_secbuf = phys_secbuf >> 8;
  4697. -  dma_wd.dma_md=(unsigned char)phys_secbuf;
  4698. -  phys_secbuf = phys_secbuf >> 8;
  4699. -  dma_wd.dma_hi=(unsigned char)phys_secbuf;
  4700.    
  4701. +static void fd_seek_done( int status )
  4702.  
  4703. -  /* Clear FIFO and switch DMA to read-mode ! */  
  4704. -  dma_wd.dma_mode_status=0x190;  
  4705. -  dma_wd.dma_mode_status=0x90;  
  4706. -  dma_wd.dma_mode_status=0x190;  
  4707. +{
  4708. +    TEST_PAGE("fd_seek_done",0);
  4709. +    DPRINT(("fd_seek_done()\n"));
  4710. +    /* set the correct speed */
  4711. +     dma_wd.fdc_speed = unit[SelectedDrive].disktype->fdc_speed;    
  4712. +    if (status & FDCSTAT_RECNF) {
  4713. +        printk( "fd%d: seek error\n", SelectedDrive );
  4714. +        /* we don't know exactly which track we are on now! */
  4715. +        unit[SelectedDrive].track = -1;
  4716. +        end_request( 0 );
  4717. +        redo_fd_request();
  4718. +    }
  4719. +    else {
  4720. +        unit[SelectedDrive].track = ReqTrack << 
  4721. +            unit[SelectedDrive].disktype->stretch;
  4722. +        NeedSeek = 0;
  4723. +        fd_rwsec();
  4724. +    }
  4725. +}
  4726.  
  4727. -  /* Transmit only 1 Sector */
  4728. -  dma_wd.fdc_acces_seccount=0x01;
  4729. -  udelay (1);  
  4730.    
  4731. +/* This does the actual reading/writing after positioning the head
  4732. + * over the correct track.
  4733. + */
  4734. +
  4735. +#ifdef TRACKBUFFER
  4736. +static int MultReadInProgress = 0;
  4737. +#endif
  4738.    
  4739. -  dma_wd.dma_mode_status=FDCSELREG_SEC | 0x100 ;
  4740. +
  4741. +static void fd_rwsec( void )
  4742. +    
  4743. +{
  4744. +    unsigned long paddr, flags;
  4745. +    unsigned int  rwflag, old_motoron;
  4746. +    unsigned int track;
  4747. +#ifdef TRACKBUFFER
  4748. +    int    single_read = 0;
  4749. +#endif
  4750. +    
  4751. +    TEST_PAGE("fd_rwsec",0);
  4752. +    DPRINT(("fd_rwsec(), Sec=%d, Access=%c\n",ReqSector, ReqCmd == WRITE ? 'w' : 'r' ));
  4753. +    if (ReqCmd == WRITE) {
  4754. +        copy_buffer( ReqData, DMABuffer );
  4755. +        cache_push( PhysDMABuffer, 512 );
  4756. +        paddr = PhysDMABuffer;
  4757. +        rwflag = 0x100;
  4758. +    }
  4759. +    else {
  4760. +#ifdef TRACKBUFFER
  4761. +        paddr = PhysTrackBuffer;
  4762. +        if (error_drive == SelectedDrive && error_track == ReqTrack
  4763. +            && error_side == ReqSide)
  4764. +          {
  4765. +            DPRINT (("fd_rwsec: single sector read after error\n"));
  4766. +            single_read = 1;
  4767. +            paddr = PhysDMABuffer;
  4768. +          }
  4769. +#else
  4770. +        paddr = PhysDMABuffer;
  4771. +#endif
  4772. +        rwflag = 0;
  4773. +    }
  4774. +
  4775. +    fd_select_side( ReqSide );
  4776. +  
  4777. +    /* Start sector of this operation */
  4778. +#ifdef TRACKBUFFER
  4779. +    FDC_WRITE( FDCREG_SECTOR, rwflag || single_read ? ReqSector : 1 );
  4780. +#else
  4781. +    FDC_WRITE( FDCREG_SECTOR, ReqSector );
  4782. +#endif
  4783. +    /* Cheat for track if stretch != 0 */
  4784. +    if (unit[SelectedDrive].disktype->stretch) {
  4785. +        track = FDC_READ( FDCREG_TRACK);
  4786. +        FDC_WRITE( FDCREG_TRACK, track >> 
  4787. +            unit[SelectedDrive].disktype->stretch);
  4788. +    }
  4789. +    udelay(40);
  4790. +  
  4791. +    /* Setup DMA */
  4792. +    TEST_PAGE("before setting DMA",paddr);
  4793. +    save_flags(flags);  
  4794. +    cli();
  4795. +    dma_wd.dma_lo = (unsigned char)paddr;
  4796. +    paddr >>= 8;
  4797. +    nop();
  4798. +    dma_wd.dma_md = (unsigned char)paddr;
  4799. +    paddr >>= 8;
  4800.    nop();
  4801. -  dma_wd.fdc_acces_seccount=sec;   
  4802. -  udelay (1);
  4803. +    dma_wd.dma_hi = (unsigned char)paddr;
  4804. +    nop();
  4805. +    restore_flags(flags);
  4806. +    TEST_PAGE("after setting DMA",ReqTrack*2+ReqSide);
  4807.    
  4808. -  /* Start Write */
  4809. -  dma_wd.dma_mode_status=FDCSELREG_STP | 0x100 ;
  4810. +    /* Clear FIFO and switch DMA to correct mode */  
  4811. +    dma_wd.dma_mode_status = 0x90 | rwflag;  
  4812. +    nop();
  4813. +    dma_wd.dma_mode_status = 0x90 | (rwflag ^ 0x100);  
  4814. +    nop();
  4815. +    dma_wd.dma_mode_status = 0x90 | rwflag;
  4816.    nop();
  4817. -  dma_wd.fdc_acces_seccount=FDCCMD_WRSEC ;
  4818. -  udelay (1);
  4819.    
  4820. -  fd_nobusy();  /* Wait for IRQ 5 */
  4821. +    /* How many sectors for DMA */
  4822. +#ifdef TRACKBUFFER
  4823. +    dma_wd.fdc_acces_seccount =
  4824. +        rwflag || single_read ? 1 : unit[SelectedDrive].disktype->spt;
  4825. +#else
  4826. +    dma_wd.fdc_acces_seccount = 1;
  4827. +#endif
  4828.    
  4829. -  restore_flags(flags);
  4830. +    udelay(40);  
  4831.    
  4832. -  fd_deselect(dr);
  4833. +    /* Start operation */
  4834. +    dma_wd.dma_mode_status = FDCSELREG_STP | rwflag;
  4835. +    udelay(40);
  4836. +    SET_IRQ_HANDLER( fd_rwsec_done );
  4837. +    dma_wd.fdc_acces_seccount =
  4838. +        (rwflag ? (FDCCMD_WRSEC | FDCCMDADD_P) :
  4839. +#ifdef TRACKBUFFER
  4840. +                  (FDCCMD_RDSEC | (single_read ? 0 : FDCCMDADD_M))
  4841. +#else
  4842. +                  FDCCMD_RDSEC
  4843. +#endif                      
  4844. +         ) | get_head_settle_flag();
  4845.  
  4846. -  udelay (10);
  4847. +    old_motoron = MotorOn;
  4848. +    MotorOn = 1;
  4849. +    NeedSeek = 1;
  4850. +    /* wait for interrupt */
  4851. +
  4852. +#ifdef TRACKBUFFER
  4853. +    if (!rwflag && !single_read) {
  4854. +        /* If reading a whole track, wait about one disk rotation and
  4855. +         * then check if all sectors are read. The FDC will even
  4856. +         * search for the first non-existant sector and need 1 sec to
  4857. +         * recognise that it isn't present :-(
  4858. +         */
  4859. +        readtrack_timer.expires = HZ/5 + 3*HZ/50 + (old_motoron ? 0 : HZ);
  4860. +                                  /* 1 rot. + 5 rot.s if motor was off  */
  4861. +        add_timer( &readtrack_timer );
  4862. +        MultReadInProgress = 1;
  4863.   }
  4864. +#endif
  4865. +    TEST_PAGE("leaving rwsec",0);
  4866. +}
  4867.  
  4868. -/*==========================================================================
  4869. -  atari_read reads a raw track of data into a track buffer
  4870. -==========================================================================*/
  4871. -static int atari_read(int dr, unsigned short tr, unsigned short sec)
  4872. -{
  4873. -  unsigned long phys_secbuf,flags;
  4874.      
  4875. -  phys_secbuf = (unsigned long) trackdata;
  4876. +#ifdef TRACKBUFFER
  4877.    
  4878. -  sec=sec+1;
  4879. +static void fd_readtrack_check( unsigned long dummy )
  4880. +  
  4881. +{    unsigned long flags, addr;
  4882.    
  4883.    save_flags(flags);  
  4884.    cli();
  4885.    
  4886. -  fd_select (dr, tr & 1);
  4887. +    TEST_PAGE("check timer",0);
  4888. +    del_timer( &readtrack_timer );
  4889.    
  4890. -  tr=tr/2;
  4891. +    if (!MultReadInProgress) {
  4892. +        /* This prevents a race condition that could arise if the
  4893. +         * interrupt is triggered while the calling of this timer
  4894. +         * callback function takes place. The IRQ function then has
  4895. +         * already cleared 'MultReadInProgress'  when control flow
  4896. +         * gets here.
  4897. +         */
  4898. +        restore_flags(flags);
  4899. +        return;
  4900. +    }
  4901.    
  4902. -  /* Setup head pos. */
  4903. -  fd_seek(dr,tr);
  4904. +    /* get the current DMA address */
  4905. +    addr = dma_wd.dma_lo & 0xff;
  4906. +    nop();
  4907. +    addr |= (dma_wd.dma_md & 0xff) << 8;
  4908. +    nop();
  4909. +    addr |= (dma_wd.dma_hi & 0xff) << 16;
  4910. +    nop();
  4911.    
  4912. +    if (addr >= PhysTrackBuffer + unit[SelectedDrive].disktype->spt*512) {
  4913. +        /* already read enough data, force an FDC interrupt to stop
  4914. +         * the read operation
  4915. +         */
  4916. +        SET_IRQ_HANDLER( NULL );
  4917. +        restore_flags(flags);
  4918. +        DPRINT(("fd_readtrack_check(): done\n"));
  4919. +        FDC_WRITE( FDCREG_CMD, FDCCMD_FORCI );
  4920. +        TEST_PAGE("Int force",0);
  4921. +        udelay(40);
  4922.  
  4923. -  /* Setup DMA */
  4924. -  dma_wd.dma_lo=(unsigned char)phys_secbuf;
  4925. -  phys_secbuf = phys_secbuf >> 8;
  4926. -  dma_wd.dma_md=(unsigned char)phys_secbuf;
  4927. -  phys_secbuf = phys_secbuf >> 8;
  4928. -  dma_wd.dma_hi=(unsigned char)phys_secbuf;
  4929. +        /* No error until now -- the FDC would have interrupted
  4930. +         * otherwise!
  4931. +         */
  4932. +        fd_rwsec_done( 0 );
  4933. +    }
  4934. +    else {
  4935. +        /* not yet finished, wait another tenth rotation */
  4936. +        restore_flags(flags);
  4937. +        DPRINT(("fd_readtrack_check(): not yet finished\n"));
  4938. +        readtrack_timer.expires = HZ/5/10;
  4939. +        add_timer( &readtrack_timer );
  4940. +    }
  4941. +}
  4942.    
  4943. +#endif
  4944.  
  4945. -  /* Clear FIFO and switch DMA to read-mode ! */  
  4946. -  dma_wd.dma_mode_status=0x90;  
  4947. -  dma_wd.dma_mode_status=0x190;  
  4948. -  dma_wd.dma_mode_status=0x90;  
  4949. -  /* Transmit only 1 Sector */
  4950. -  dma_wd.fdc_acces_seccount=0x01;
  4951. -  udelay (1);
  4952. +static void fd_rwsec_done( int status )
  4953.    
  4954. -  dma_wd.dma_mode_status=FDCSELREG_SEC;
  4955. -  nop();
  4956. -  dma_wd.fdc_acces_seccount=sec;   
  4957. -  udelay (1);
  4958. +{
  4959. +    unsigned int track;
  4960. +#ifdef TRACKBUFFER
  4961. +    int single_read = MultReadInProgress == -1;
  4962. +#endif
  4963. +
  4964. +    TEST_PAGE("rwsec_done",ReqTrack*2+ReqSide);
  4965. +    DPRINT(("fd_rwsec_done()\n"));
  4966. +
  4967. +#ifdef TRACKBUFFER
  4968. +    if (ReqCmd == READ && !MultReadInProgress) return;
  4969. +    MultReadInProgress = 0;
  4970.    
  4971. -  /* Start READ */
  4972. -  dma_wd.dma_mode_status=FDCSELREG_STP;
  4973. +    if (ReqCmd == READ && !single_read)
  4974. +        del_timer( &readtrack_timer );
  4975. +#endif
  4976. +
  4977. +    /* Correct the track if stretch != 0 */
  4978. +    if (unit[SelectedDrive].disktype->stretch) {
  4979. +        track = FDC_READ( FDCREG_TRACK);
  4980. +        FDC_WRITE( FDCREG_TRACK, track << 
  4981. +            unit[SelectedDrive].disktype->stretch);
  4982. +    }
  4983. +
  4984. +#ifndef TRACKBUFFER
  4985. +    dma_wd.dma_mode_status = 0x90;
  4986.    nop();
  4987. -  dma_wd.fdc_acces_seccount=FDCCMD_RDSEC ;
  4988. -  udelay (1);
  4989. +    if (!(dma_wd.dma_mode_status & 0x01)) {
  4990. +        printk( "fd%d: DMA error\n", SelectedDrive );
  4991. +        goto err_end;
  4992. +    }
  4993. +#endif
  4994.      
  4995. -  fd_nobusy();  /* Wait for IRQ 5 */
  4996. +    if (ReqCmd == WRITE && (status & FDCSTAT_WPROT)) {
  4997. +        printk( "fd%d: is write protected\n", SelectedDrive );
  4998. +        goto err_end;
  4999. +    }    
  5000. +    if ((status & FDCSTAT_RECNF)
  5001. +#ifdef TRACKBUFFER
  5002. +        /* RECNF is no error after a multiple read when the FDC
  5003. +         * searched for a non-existant sector!
  5004. +         */
  5005. +        && !(ReqCmd == READ && !single_read &&
  5006. +             FDC_READ(FDCREG_SECTOR) > unit[SelectedDrive].disktype->spt)
  5007. +#endif
  5008. +       ) {
  5009. +        if (Probing) {
  5010. +            if (unit[SelectedDrive].disktype > disk_type) {
  5011. +                /* try another disk type */
  5012. +                unit[SelectedDrive].disktype--;
  5013. +            }
  5014. +            else
  5015. +                Probing=0;
  5016. +        } else {    
  5017. +/* record not found, but not probing. Maybe stretch wrong ? Restart probing */
  5018. +            if (unit[SelectedDrive].autoprobe) {
  5019. +                unit[SelectedDrive].disktype = disk_type + NUM_DISK_TYPES-1;
  5020. +                Probing = 1;
  5021. +            }
  5022. +        }
  5023. +        if (Probing) {
  5024. +            dma_wd.fdc_speed = unit[SelectedDrive].disktype->fdc_speed;
  5025. +            setup_req_params( SelectedDrive );
  5026. +#ifdef TRACKBUFFER
  5027. +            BufferDrive = -1;
  5028. +#endif
  5029. +            do_fd_action( SelectedDrive );
  5030. +            return;
  5031. +        }
  5032.    
  5033. -  restore_flags(flags);
  5034. +        printk( "fd%d: sector %d not found\n", SelectedDrive,
  5035. +                FDC_READ (FDCREG_SECTOR) );
  5036. +        goto err_end;
  5037. +    }
  5038. +    if (status & FDCSTAT_CRC) {
  5039. +        printk( "fd%d: CRC error\n", SelectedDrive );
  5040. +        goto err_end;
  5041. +    }
  5042. +    if (status & FDCSTAT_LOST) {
  5043. +        printk( "fd%d: lost data\n", SelectedDrive );
  5044. +        goto err_end;
  5045. +    }
  5046.    
  5047. -  fd_deselect(dr);
  5048. +    Probing = 0;
  5049.    
  5050. -    return 0;
  5051. +    if (ReqCmd == READ) {
  5052. +#ifdef TRACKBUFFER
  5053. +        if (single_read)
  5054. +          {
  5055. +            cache_clear (PhysDMABuffer, 512);
  5056. +            copy_buffer (DMABuffer, ReqData);
  5057. +          }
  5058. +        else
  5059. +          {
  5060. +            cache_clear (PhysTrackBuffer, MAX_SECTORS * 512);
  5061. +            BufferDrive = SelectedDrive;
  5062. +            BufferSide  = ReqSide;
  5063. +            BufferTrack = ReqTrack;
  5064. +            copy_buffer (SECTOR_BUFFER (ReqSector), ReqData);
  5065. +          }
  5066. +#else
  5067. +        cache_clear( PhysDMABuffer, 512 );
  5068. +        copy_buffer( DMABuffer, ReqData );
  5069. +#endif
  5070. +    }
  5071. +  
  5072. +    if (++ReqCnt < 2) {
  5073. +        /* read next sector */
  5074. +        setup_req_params( SelectedDrive );
  5075. +        do_fd_action( SelectedDrive );
  5076. +    }
  5077. +    else {
  5078. +        /* all sectors finished */
  5079. +        end_request( 1 );
  5080. +        redo_fd_request();
  5081. +    }
  5082. +    return;
  5083. +  
  5084. +  err_end:
  5085. +#ifdef TRACKBUFFER
  5086. +    BufferDrive = -1;
  5087. +    if (ReqCmd == READ && !single_read)
  5088. +      {
  5089. +        FDC_WRITE (FDCREG_CMD, FDCCMD_FORCI);
  5090. +        udelay (40);
  5091. +        error_drive = SelectedDrive;
  5092. +        error_track = ReqTrack;
  5093. +        error_side = ReqSide;
  5094. +        setup_req_params (SelectedDrive);
  5095. +        do_fd_action (SelectedDrive);
  5096. +        return;
  5097. +      }
  5098. +#endif
  5099. +    end_request( 0 );
  5100. +    redo_fd_request();
  5101.  }
  5102.  
  5103. +
  5104. +/* The (noop) seek operation here is needed to make the WP bit in the
  5105. + * FDC status register accessible for check_change. If the last disk
  5106. + * operation would have been a RDSEC, this bit would always read as 0
  5107. + * no matter what :-( To save time, the seek goes to the track we're
  5108. + * already on.
  5109. + */
  5110. +
  5111. +static void finish_fdc( void )
  5112. +
  5113. +{    unsigned long flags;
  5114. +
  5115. +    TEST_PAGE("finish_fdc",0);
  5116. +
  5117. +    if (NeedSeek)
  5118. +      {
  5119. +        FDC_WRITE (FDCREG_DATA, unit[SelectedDrive].track);
  5120. +        SET_IRQ_HANDLER (NULL);
  5121. +        FDC_WRITE (FDCREG_CMD, FDCCMD_SEEK);
  5122. +
  5123. +        MotorOn = 1;
  5124. +        /* don't wait for IRQ, just go on */
  5125. +      }
  5126. +
  5127. +    if ((timer_active & (1 << FLOPPY_TIMER)) &&
  5128. +        timer_table[FLOPPY_TIMER].expires < jiffies + 5)
  5129. +        /* If the check for a disk change is done too early after this
  5130. +         * last seek command, the WP bit still reads wrong :-((
  5131. +         */
  5132. +        timer_table[FLOPPY_TIMER].expires = jiffies + 5;
  5133. +    else
  5134. +        START_CHECK_CHANGE_TIMER( CHECK_CHANGE_DELAY );
  5135. +    del_timer( &motor_off_timer );
  5136. +    START_MOTOR_OFF_TIMER( FD_MOTOR_OFF_DELAY );
  5137. +
  5138. +    save_flags(flags);
  5139. +    cli();
  5140. +    stdma_release();
  5141. +    fdc_busy = 0;
  5142. +    wake_up( &fdc_wait );
  5143. +    restore_flags(flags);
  5144. +
  5145. +    DPRINT(("finish_fdc() finished\n"));
  5146. +    TEST_PAGE("end of finish_fdc",0);
  5147. +}
  5148. +
  5149. +
  5150.  /*
  5151.   * Note that MAX_ERRORS=X doesn't imply that we retry every bad read
  5152.   * max X times - some types of errors increase the errorcount by 2 or
  5153. @@ -372,13 +1003,6 @@
  5154.   */
  5155.  #define MAX_ERRORS 12
  5156.  
  5157. -/*
  5158. - * The driver is trying to determine the correct media format
  5159. - * while probing is set. rw_interrupt() clears it after a
  5160. - * successful access.
  5161. - */
  5162. -static int probing = 0;
  5163. -
  5164.  /* Prevent "aliased" accesses. */
  5165.  static fd_ref[4] = { 0,0,0,0 };
  5166.  static fd_device[4] = { 0,0,0,0 };
  5167. @@ -392,50 +1016,114 @@
  5168.  /* Current error count. */
  5169.  #define CURRENT_ERRORS (CURRENT->errors)
  5170.  
  5171. -static void floppy_off (unsigned int nr)
  5172. -{
  5173. -}
  5174.  
  5175. +/* dummy for blk.h */
  5176. +static void floppy_off( unsigned int nr) {}
  5177.  
  5178.  
  5179. -/*
  5180. - * floppy-change is never called from an interrupt, so we can relax a bit
  5181. - * here, sleep etc. Note that floppy-on tries to set current_DOR to point
  5182. - * to the desired drive, but it will probably not survive the sleep if
  5183. - * several floppies are used at the same time: thus the loop.
  5184. +/* The detection of disk changes is a dark chapter in Atari history :-(
  5185. + * Because the "Drive ready" signal isn't present in the Atari
  5186. + * hardware, one has to rely on the "Write Protect". This works fine,
  5187. + * as long as no write protected disks are used. TOS solves this
  5188. + * problem by introducing tri-state logic ("maybe changed") and
  5189. + * looking at the serial number in block 0. This isn't possible for
  5190. + * Linux, since the floppy driver can't make assumptions about the
  5191. + * filesystem used on the disk and thus the contents of block 0. I've
  5192. + * choosen the method to always say "The disk was changed" if it is
  5193. + * unsure whether it was. This implies that every open or mount
  5194. + * invalidates the disk buffers if you work with write protected
  5195. + * disks. But at least this is better than working with incorrect data
  5196. + * due to unrecognised disk changes.
  5197.   */
  5198. -int atari_floppy_change(struct buffer_head * bh)
  5199. -{
  5200. +
  5201. +int atari_floppy_change( struct buffer_head * bh )
  5202. +
  5203. +{    unsigned int drive = (bh->b_dev & 0x03);
  5204. +
  5205. +    if (MAJOR(bh->b_dev) != MAJOR_NR) {
  5206. +        printk("floppy_changed: not a floppy\n");
  5207. +        return 0;
  5208. +    }
  5209. +    
  5210. +    if (test_bit (drive, &fake_change)) {
  5211. +        /* simulated change (e.g. after formatting) */
  5212. +        clear_bit (drive, &fake_change);
  5213. +        goto is_changed;
  5214. +    }
  5215. +    if (test_bit (drive, &changed_floppies)) {
  5216. +        /* surely changed (the WP signal changed at least once) */
  5217. +      is_changed:
  5218. +        clear_bit (drive, &changed_floppies);
  5219. +        goto ret_changed;
  5220. +    }
  5221. +    if (unit[drive].wpstat) {
  5222. +        /* WP is on -> could be changed: to be sure, buffers should be
  5223. +         * invalidated...
  5224. +         */
  5225. +      ret_changed:
  5226. +#ifdef TRACKBUFFER
  5227. +        BufferDrive = -1;
  5228. +        error_drive = -1;
  5229. +#endif
  5230. +        
  5231. +        unit[drive].disktype = NULL;
  5232. +        return 1;
  5233. +    }
  5234. +
  5235. +    /* It doesn't make sense to read or write block 0 (described by
  5236. +     * bh) here, because it doesn't answer our question :-(
  5237. +     */
  5238. +
  5239.      return 0;
  5240.  }
  5241.  
  5242. +
  5243.  static __inline__ void copy_buffer(void *from, void *to)
  5244. -{
  5245. -  ulong *p1,*p2;
  5246. -  int cnt;
  5247.  
  5248. -  p1 = (ulong *)from;
  5249. -  p2 = (ulong *)to;
  5250. +{    ulong    *p1 = (ulong *)from, *p2 = (ulong *)to;
  5251. +    int        cnt;
  5252.  
  5253. -  for (cnt = 0; cnt < 512/4; cnt++)
  5254. +    for( cnt = 512/4; cnt; cnt-- )
  5255.      *p2++ = *p1++;
  5256.  }
  5257.  
  5258.  
  5259. +/* This sets up the global variables describing the current request. */
  5260. +
  5261. +static void setup_req_params( int drive )
  5262. +
  5263. +{    int block = ReqBlock + ReqCnt;
  5264. +
  5265. +    ReqTrack = block / unit[drive].disktype->spt;
  5266. +    ReqSector = block - ReqTrack * unit[drive].disktype->spt + 1;
  5267. +    ReqSide = ReqTrack & 1;
  5268. +    ReqTrack >>= 1;
  5269. +    ReqData = ReqBuffer + 512 * ReqCnt;
  5270. +
  5271. +#ifdef TRACKBUFFER
  5272. +    if (error_drive == drive
  5273. +        && (error_track != ReqTrack || error_side != ReqSide))
  5274. +      error_drive = -1;
  5275. +#endif
  5276. +
  5277. +    DPRINT(("Request params: Si=%d Tr=%d Se=%d Data=%08lx\n",ReqSide, ReqTrack, ReqSector, ReqData ));
  5278. +}
  5279. +
  5280. +
  5281.  static void redo_fd_request(void)
  5282. +
  5283.  {
  5284. -    unsigned int block, track, sector;
  5285. -    int device, drive, cnt;
  5286. -    struct floppy_struct *floppy;
  5287. -    char *data;
  5288. +    int device, drive, type;
  5289. +    struct atari_floppy_struct *floppy;
  5290.  
  5291. +    TEST_PAGE("redo_fd_request",0);
  5292. +    if (CURRENT && CURRENT->dev < 0)
  5293. +        goto the_end;
  5294.    
  5295. -    if (CURRENT && CURRENT->dev < 0) return;
  5296. +repeat:
  5297.  
  5298. -    repeat:
  5299. -    
  5300. -  if(!CURRENT)
  5301. -    return;
  5302. +    if (!CURRENT)
  5303. +        goto the_end;
  5304.  
  5305.      if (MAJOR(CURRENT->dev) != MAJOR_NR)
  5306.          panic(DEVICE_NAME ": request list destroyed");
  5307. @@ -445,59 +1133,74 @@
  5308.              panic(DEVICE_NAME ": block not locked");
  5309.      }
  5310.  
  5311. -    probing = 0;
  5312.      device = MINOR(CURRENT_DEVICE);
  5313. +    drive = device & 3;
  5314. +    type = device >> 2;
  5315. +    floppy = &unit[drive];
  5316. +    
  5317. +    if (!floppy->connected) {
  5318. +        /* drive not connected */
  5319. +        printk( "Unknown Device: fd%d\n", drive );
  5320. +        end_request(0);
  5321. +        goto repeat;
  5322. +    }
  5323.          
  5324. -    if (CURRENT_DEVICE == 0x200 ) {
  5325. -        /* manual selection */
  5326. -        drive = 0;
  5327. -        floppy = unit + drive;
  5328. +    if (type == 0) {
  5329. +        if (!floppy->disktype) {
  5330. +            Probing = 1;
  5331. +            floppy->disktype  = disk_type + NUM_DISK_TYPES-1;
  5332. +            floppy->autoprobe = 1;
  5333.      } 
  5334. -     else
  5335. -    {
  5336. -     printk("Unknown Device !\n");
  5337. -     return;
  5338. +    } 
  5339. +    else {
  5340. +        /* user supplied disk type */
  5341. +        --type;
  5342. +        if (type >= NUM_DISK_TYPES) {
  5343. +            printk( "fd%d: invalid disk format", drive );
  5344. +            end_request( 0 );
  5345. +            goto repeat;
  5346. +        }
  5347. +        floppy->disktype = &disk_type[type];
  5348. +        floppy->autoprobe = 0;
  5349.      }
  5350.      
  5351. -    for (cnt = 0; cnt < 2; cnt++) {
  5352. -        block = CURRENT->sector + cnt;
  5353. -        if ((int)block > floppy->blocks) {
  5354. +    if (CURRENT->sector + 1 > floppy->disktype->blocks) {
  5355.              end_request(0);
  5356.              goto repeat;
  5357.          }
  5358.  
  5359. -        track = block / floppy->dtype->sects;
  5360. -        sector = block - track * floppy->dtype->sects;
  5361. -        data = CURRENT->buffer + 512 * cnt;
  5362. +    /* stop deselect timer */
  5363. +    del_timer( &motor_off_timer );
  5364.          
  5365. +    ReqCnt = 0;
  5366. +    ReqCmd = CURRENT->cmd;
  5367. +    ReqBlock = CURRENT->sector;
  5368. +    ReqBuffer = CURRENT->buffer;
  5369. +    setup_req_params( drive );
  5370. +    do_fd_action( drive );
  5371.  
  5372. -        switch (CURRENT->cmd) {
  5373. -          case READ:
  5374. -            atari_read(device,track,sector);
  5375. -            copy_buffer(trackdata,data);
  5376. -            break;
  5377. +    return;
  5378.  
  5379. -          case WRITE:
  5380. -            copy_buffer(data,trackdata);
  5381. -            atari_write(device,track,sector);
  5382. -            break;
  5383. +  the_end:
  5384. +    finish_fdc();
  5385. +}
  5386.  
  5387. -          default:
  5388. -            printk("do_fd_request: unknown command\n");
  5389. -            end_request(0);
  5390. -            goto repeat;
  5391. -        }
  5392. -    }
  5393.  
  5394. -    end_request(1);
  5395. -    goto repeat;
  5396. -}
  5397. +void do_fd_request(void)
  5398. +
  5399. +{     unsigned long flags;
  5400. +
  5401. +    save_flags(flags);
  5402. +    cli();
  5403. +    while( fdc_busy ) sleep_on( &fdc_wait );
  5404. +    fdc_busy = 1;
  5405. +    stdma_lock( floppy_irq, 0 );
  5406. +    restore_flags(flags);
  5407.  
  5408. -static void do_fd_request(void)
  5409. -{ 
  5410.      redo_fd_request();
  5411.  }
  5412.  
  5413. +
  5414.  static int fd_ioctl(struct inode *inode, struct file *filp,
  5415.              unsigned int cmd, unsigned long param)
  5416.  {
  5417. @@ -505,53 +1208,102 @@
  5418.      return -EINVAL;
  5419.  }
  5420.  
  5421. -/*======================================================================
  5422. -  Return unit ID number of given disk
  5423. -======================================================================*/
  5424. -#ifdef __notneeded__
  5425. -static unsigned long get_drive_id(int drive)
  5426. -{
  5427. -    return FD_HD_3;
  5428. -}
  5429. -#endif
  5430.  
  5431. -static void fd_probe(int drive)
  5432. +/* Initialize the 'unit' variable for drive 'drive' */
  5433. +
  5434. +static void fd_probe( int drive )
  5435.  {
  5436. -    unit[drive].type = NULL;
  5437. -    if (drive != 0)
  5438. -        /* At the moment, only one floppy drive is supported */
  5439. +    unit[drive].connected = 0;
  5440. +    unit[drive].disktype  = NULL;
  5441. +
  5442. +    if (!fd_test_drive_present( drive ))
  5443.          return;
  5444.  
  5445. -#ifdef CONFIG_FLOPPY_DD_ONLY
  5446. -    unit[drive].type = &drive_types[1]; /* DD */
  5447. -    dma_wd.fdc_speed = 0;
  5448. -#else
  5449. -    unit[drive].type = &drive_types[0]; /* HD */
  5450. -    dma_wd.fdc_speed = 3;
  5451. -#endif
  5452. +    unit[drive].connected = 1;
  5453. +    unit[drive].track     = 0;
  5454. +    unit[drive].steprate  = FDCSTEP_3;
  5455. +    MotorOn = 1;    /* from probe restore operation! */
  5456. +}
  5457. +
  5458. +
  5459. +/* This function tests the physical presence of a floppy drive (not
  5460. + * whether a disk is inserted). This is done by issuing a restore
  5461. + * command, waiting max. 2 seconds (that should be enough to move the
  5462. + * head across the whole disk) and looking at the state of the "TR00"
  5463. + * signal. This should now be raised if there is a drive connected
  5464. + * (and there is no hardware failure :-) Otherwise, the drive is
  5465. + * declared absent.
  5466. + */
  5467. +
  5468. +static int fd_test_drive_present( int drive )
  5469. +
  5470. +{    unsigned long timeout;
  5471. +    unsigned char status;
  5472. +    int              ok;
  5473. +    
  5474. +    if (drive > 1) return( 0 );
  5475. +    fd_select_drive( drive );
  5476. +
  5477. +    /* disable interrupt temporarily */
  5478. +    mfp.int_en_b &= 0x7f;
  5479. +    FDC_WRITE( FDCREG_CMD, FDCCMD_RESTORE | FDCSTEP_6 );
  5480. +
  5481. +    for( ok = 0, timeout = jiffies + 2*HZ+HZ/2; jiffies < timeout; ) {
  5482. +        if (!(mfp.par_dt_reg & 0x20))
  5483. +            break;
  5484. +    }
  5485. +
  5486. +    status = FDC_READ( FDCREG_STATUS );
  5487. +    ok = (status & FDCSTAT_TR00) != 0;
  5488.  
  5489. -    unit[drive].dtype = &data_types[0]; /* only one type */
  5490. -    unit[drive].track = -1;
  5491. +    /* force interrupt to abort restore operation (FDC would try
  5492. +     * about 50 seconds!) */
  5493. +    FDC_WRITE( FDCREG_CMD, FDCCMD_FORCI );
  5494. +    udelay(40);
  5495. +    status = FDC_READ( FDCREG_STATUS );
  5496. +    udelay(20);
  5497. +
  5498. +    if (ok) {
  5499. +        /* dummy seek command to make WP bit accessible */
  5500. +        FDC_WRITE( FDCREG_DATA, 0 );
  5501. +        FDC_WRITE( FDCREG_CMD, FDCCMD_SEEK );
  5502. +        while( mfp.par_dt_reg & 0x20 )
  5503. +            ;
  5504. +        status = FDC_READ( FDCREG_STATUS );
  5505. +    }
  5506.  
  5507. -    unit[drive].sects = unit[drive].dtype->sects * unit[drive].type->sect_mult;
  5508. -    unit[drive].blocks = unit[drive].type->heads * unit[drive].type->tracks *
  5509. -                         unit[drive].sects;
  5510. +    mfp.int_pn_b = 0x7f;
  5511. +    mfp.int_en_b |= 0x80;
  5512.  
  5513. -    unit[drive].disk = -1;
  5514. -    unit[drive].motor = 0;
  5515. -    unit[drive].busy = 0;
  5516. -    unit[drive].status = -1;
  5517. +    return( ok );
  5518.  }
  5519.  
  5520. -static void config_types(void)
  5521. +
  5522. +/* Look how many and which kind of drives are connected. If there are
  5523. + * floppies, additionally start the disk-change and motor-off timers.
  5524. + */
  5525. +
  5526. +static void config_types( void )
  5527. +
  5528.  {
  5529. -    int drive;
  5530. +    int drive, cnt = 0;
  5531. +
  5532. +    /* for probing drives, set the FDC speed to 8 MHz */
  5533. +    dma_wd.fdc_speed = 0;
  5534.  
  5535.      printk("Probing floppy drive(s):\n");
  5536. -    for (drive = 0; drive < FD_MAX_UNITS; drive++) {
  5537. -        fd_probe(drive);
  5538. -        if (unit[drive].type != NULL)
  5539. -            printk("%d: %s\n", drive, unit[drive].type->name);
  5540. +    for( drive = 0; drive < FD_MAX_UNITS; drive++ ) {
  5541. +        fd_probe( drive );
  5542. +        if (unit[drive].connected) {
  5543. +            printk("fd%d\n", drive);
  5544. +            ++cnt;
  5545. +        }
  5546. +    }
  5547. +
  5548. +    if (cnt > 0) {
  5549. +        START_MOTOR_OFF_TIMER( FD_MOTOR_OFF_DELAY );
  5550. +        if (cnt == 1) fd_select_drive( 0 );
  5551. +        START_CHECK_CHANGE_TIMER( CHECK_CHANGE_DELAY );
  5552.      }
  5553.  }
  5554.  
  5555. @@ -560,7 +1312,9 @@
  5556.   * /dev/PS0 etc), and disallows simultaneous access to the same
  5557.   * drive with different device numbers.
  5558.   */
  5559. -static int floppy_open(struct inode *inode, struct file *filp)
  5560. +
  5561. +static int floppy_open( struct inode *inode, struct file *filp )
  5562. +
  5563.  {
  5564.    int drive;
  5565.    int old_dev;
  5566. @@ -578,16 +1332,24 @@
  5567.    if (old_dev && old_dev != inode->i_rdev)
  5568.      invalidate_buffers(old_dev);
  5569.  
  5570. -  if (filp && filp->f_mode)
  5571. -    check_disk_change(inode->i_rdev);
  5572. -
  5573. +    if (filp && filp->f_mode) {
  5574. +        check_disk_change( inode->i_rdev );
  5575. +        if (filp->f_mode & 2) {
  5576. +            if (unit[drive].wpstat) {
  5577. +                floppy_release(inode, filp);
  5578. +                return -EROFS;
  5579. +            }
  5580. +        }
  5581. +    }
  5582.  
  5583.    return 0;
  5584.  }
  5585.  
  5586. -static void floppy_release(struct inode * inode, struct file * filp)
  5587. +
  5588. +static void floppy_release( struct inode * inode, struct file * filp )
  5589. +
  5590.  {
  5591. -  sync_dev(inode->i_rdev);
  5592. +    fsync_dev(inode->i_rdev);
  5593.    if (!fd_ref[inode->i_rdev & 3]--) {
  5594.      printk("floppy_release with fd_ref == 0");
  5595.      fd_ref[inode->i_rdev & 3] = 0;
  5596. @@ -607,25 +1369,37 @@
  5597.      block_fsync        /* fsync */
  5598.  };
  5599.  
  5600. -#ifdef __notneeded__
  5601. -static void fd_block_done(struct intframe *fp, void *data)
  5602. -{
  5603. -}
  5604. -#endif
  5605.  
  5606.  void atari_floppy_init(void)
  5607. -{
  5608. -  int i;
  5609. +
  5610. +{    int i;
  5611.  
  5612.    if (register_blkdev(MAJOR_NR,"fd",&floppy_fops)) {
  5613.      printk("Unable to get major %d for floppy\n",MAJOR_NR);
  5614.      return;
  5615.    }
  5616. +
  5617.    /* initialize variables */
  5618. -  selected = -1;
  5619. +    SelectedDrive = -1;
  5620. +#ifdef TRACKBUFFER
  5621. +    BufferDrive = -1;
  5622. +    error_drive = -1;
  5623. +#endif
  5624.  
  5625. -  /* memory returned by atari_stram_alloc is identity mapped */
  5626. -  trackdata = atari_stram_alloc (512);
  5627. +    /* initialize motor-off timer */
  5628. +    timer_table[FLOPPY_TIMER].fn = check_change;
  5629. +    timer_active &= ~(1 << FLOPPY_TIMER);
  5630. +
  5631. +    /* The ST-Ram buffers are now allocated in
  5632. +     * atari_floppy_alloc_buffers(), which is called by
  5633. +     * blk_dev_init(). This is because floppy_init() is called after
  5634. +     * mem_init() and stram_alloc() isn't possible any more here.
  5635. +     */
  5636. +    PhysDMABuffer = (unsigned long) VTOP(DMABuffer);
  5637. +#ifdef TRACKBUFFER
  5638. +    PhysTrackBuffer = (unsigned long) VTOP(TrackBuffer);
  5639. +    BufferDrive = BufferSide = BufferTrack = -1;
  5640. +#endif
  5641.  
  5642.    for (i = 0; i < FD_MAX_UNITS; i++) {
  5643.        unit[i].track = -1;
  5644. @@ -636,3 +1410,25 @@
  5645.  
  5646.    config_types();
  5647.  }
  5648. +
  5649. +
  5650. +/* This function is called by blk_dev_init() to give the floppy driver
  5651. + * a chance to allocate some ST-Ram
  5652. + */
  5653. +
  5654. +unsigned long atari_floppy_alloc_buffers( unsigned long mem_start )
  5655. +
  5656. +{
  5657. +#ifdef TRACKBUFFER
  5658. +    DMABuffer = atari_stram_alloc( (MAX_SECTORS+1)*512, &mem_start );
  5659. +    TrackBuffer = DMABuffer + 512;
  5660. +#else
  5661. +    DMABuffer = atari_stram_alloc( 512, &mem_start );
  5662. +#endif
  5663. +    return( mem_start );
  5664. +}
  5665. +
  5666. +
  5667. +/* Local Variables: */
  5668. +/* tab-width: 4     */
  5669. +/* End:             */
  5670. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/drivers/block/blk.h linux-0.9pl4/drivers/block/blk.h
  5671. --- linux-0.9pl3/drivers/block/blk.h    Sun Aug 14 10:30:43 1994
  5672. +++ linux-0.9pl4/drivers/block/blk.h    Mon Nov  7 22:13:16 1994
  5673. @@ -27,8 +27,8 @@
  5674.  /*
  5675.   * Ok, this is an expanded form so that we can use the same
  5676.   * request for paging requests when that is implemented. In
  5677. - * paging, 'bh' is NULL, and 'waiting' is used to wait for
  5678. - * read/write completion.
  5679. + * paging, 'bh' is NULL, and the semaphore is used to wait
  5680. + * for read/write completion.
  5681.   */
  5682.  struct request {
  5683.      int dev;        /* -1 if no request */
  5684. @@ -38,7 +38,7 @@
  5685.      unsigned long nr_sectors;
  5686.      unsigned long current_nr_sectors;
  5687.      char * buffer;
  5688. -    struct task_struct * waiting;
  5689. +    struct semaphore * sem;
  5690.      struct buffer_head * bh;
  5691.      struct buffer_head * bhtail;
  5692.      struct request * next;
  5693. @@ -205,6 +205,15 @@
  5694.  #define DEVICE_ON(device)
  5695.  #define DEVICE_OFF(device)
  5696.  
  5697. +#elif (MAJOR_NR == ACSI_MAJOR)
  5698. +
  5699. +#define DEVICE_NAME "ACSI"
  5700. +#define DEVICE_INTR do_acsi
  5701. +#define DEVICE_REQUEST do_acsi_request
  5702. +#define DEVICE_NR(device) (MINOR(device) >> 4)
  5703. +#define DEVICE_ON(device)
  5704. +#define DEVICE_OFF(device)
  5705. +
  5706.  #else
  5707.  
  5708.  #error "unknown blk device"
  5709. @@ -252,7 +261,6 @@
  5710.  {
  5711.      struct request * req;
  5712.      struct buffer_head * bh;
  5713. -    struct task_struct * p;
  5714.  
  5715.      req = CURRENT;
  5716.      req->errors = 0;
  5717. @@ -270,6 +278,7 @@
  5718.          req->bh = bh->b_reqnext;
  5719.          bh->b_reqnext = NULL;
  5720.          bh->b_uptodate = uptodate;
  5721. +        if (!uptodate) bh->b_req = 0; /* So no "Weird" errors */
  5722.          unlock_buffer(bh);
  5723.          if ((bh = req->bh) != NULL) {
  5724.              req->current_nr_sectors = bh->b_size >> 9;
  5725. @@ -283,12 +292,8 @@
  5726.      }
  5727.      DEVICE_OFF(req->dev);
  5728.      CURRENT = req->next;
  5729. -    if ((p = req->waiting) != NULL) {
  5730. -        req->waiting = NULL;
  5731. -        p->state = TASK_RUNNING;
  5732. -        if (p->counter > current->counter)
  5733. -            need_resched = 1;
  5734. -    }
  5735. +    if (req->sem != NULL)
  5736. +        up(req->sem);
  5737.      req->dev = -1;
  5738.      wake_up(&wait_for_request);
  5739.  }
  5740. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/drivers/block/falhd.c linux-0.9pl4/drivers/block/falhd.c
  5741. --- linux-0.9pl3/drivers/block/falhd.c    Tue Sep 27 22:21:42 1994
  5742. +++ linux-0.9pl4/drivers/block/falhd.c    Mon Nov  7 22:14:45 1994
  5743. @@ -20,11 +20,6 @@
  5744.   *  Modified 1994 for ATARI IDE controller support by Bjoern Brauel
  5745.   */
  5746.   
  5747. -/*
  5748. - *  08/08/94 changes for proper Seagate recognition, debug messages 
  5749. - *  by Helmut Neukirchen, hn@pool.informatik.rwth-aachen
  5750. - */
  5751. -
  5752.  #include <linux/errno.h>
  5753.  #include <linux/signal.h>
  5754.  #include <linux/sched.h>
  5755. @@ -38,6 +33,7 @@
  5756.  #include <linux/atarihw.h>
  5757.  #include <linux/atarihdreg.h>
  5758.  #include <linux/atariints.h>
  5759. +#include <linux/atari_stdma.h>
  5760.  
  5761.  #include <asm/system.h>
  5762.  #include <asm/io.h>
  5763. @@ -53,6 +49,7 @@
  5764.  #define RECAL_FREQ      4    /* Recalibrate every 4th retry */
  5765.  #define MAX_HD        2
  5766.  
  5767. +extern void hd_interrupt (struct intframe *, void *);
  5768.  static void recal_intr(void);
  5769.  static void bad_rw_intr(void);
  5770.  
  5771. @@ -70,7 +67,7 @@
  5772.  struct hd_i_struct {
  5773.      unsigned int head,sect,cyl,wpcom,lzone,ctl;
  5774.      };
  5775. -static struct hd_i_struct hd_info[] = { {0,0,0,0,0,0},{0,0,0,0,0,0} };
  5776. +struct hd_i_struct hd_info[] = { {0,0,0,0,0,0},{0,0,0,0,0,0} };
  5777.  static int NR_HD = 0;
  5778.  
  5779.  static struct hd_struct hd[MAX_HD<<6]={{0,0},};
  5780. @@ -282,7 +279,7 @@
  5781.   * doing a reset and a retry seems to result in an eternal loop. Right now I
  5782.   * ignore it, and just set the timeout.
  5783.   */
  5784. -static void unexpected_hd_interrupt(void)
  5785. +void unexpected_hd_interrupt(void)
  5786.  {
  5787.      printk("Unexpected HD interrupt\n");
  5788.      SET_TIMER;
  5789. @@ -357,8 +354,9 @@
  5790.          MINOR(CURRENT->dev), CURRENT->sector, i, CURRENT-> 
  5791.          buffer);
  5792.  #endif
  5793. -    if (!i || (CURRENT->bh && !SUBSECTOR(i)))
  5794. +    if (!i || (CURRENT->bh && !SUBSECTOR(i))) {
  5795.          end_request(1);
  5796. +    }
  5797.      if (i > 0) {
  5798.          SET_INTR(&read_intr);
  5799.          return;
  5800. @@ -398,8 +396,9 @@
  5801.      i = --CURRENT->nr_sectors;
  5802.      --CURRENT->current_nr_sectors;
  5803.      CURRENT->buffer += 512;
  5804. -    if (!i || (CURRENT->bh && !SUBSECTOR(i)))
  5805. +    if (!i || (CURRENT->bh && !SUBSECTOR(i))) {
  5806.          end_request(1);
  5807. +    }
  5808.      if (i > 0) {
  5809.        SET_INTR(&write_intr);
  5810.          port_write(HD_DATA,CURRENT->buffer,15);
  5811. @@ -462,7 +461,7 @@
  5812.      nsect = CURRENT->nr_sectors;
  5813.      if (dev >= (NR_HD<<6) || block >= hd[dev].nr_sects) {
  5814.  #ifdef DEBUG
  5815. -        printk("hd : attempted read for sector %d past end of device at sector %d.\n",
  5816. +        printk("hd%d : attempted read for sector %d past end of device at sector %d.\n",
  5817.                 block, hd[dev].nr_sects);
  5818.  #endif
  5819.          end_request(0);
  5820. @@ -604,33 +603,26 @@
  5821.      NULL        /* next */
  5822.  };
  5823.      
  5824. -/*te******************************************************************
  5825. +/*******************************************************************
  5826.   *
  5827.   * hd_interrupt routine
  5828.   *   Test, if this is a harddisk interrupt and call
  5829.   *   the irq handler
  5830.   *   Otherwise ignore this interrupt.
  5831.   *
  5832. - ********************************************************/
  5833. -static void hd_interrupt (struct intframe *fp, void *data)
  5834. + *******************************************************************/
  5835. +extern void hd_interrupt (struct intframe *fp, void *data)
  5836.  {
  5837. -void (*hd_irq_handler)(void) = DEVICE_INTR;
  5838. +  void (*hd_irq_handler)(void) = DEVICE_INTR;
  5839.  
  5840. -/* Test, if this is a harddisk interrupt. MSB(0xdd2030) = 1 (Amiga only) */
  5841. -/* GK: this has to be changed for Atari FALCON.
  5842. - * Is there any way to determine if harddisk did interrupt ?
  5843. - */
  5844. -if (1 /*inb (HD_IRQ_TEST) & 0x7f*/)
  5845. -  {
  5846.    DEVICE_INTR = NULL;
  5847.    timer_active &= ~(1 << HD_TIMER);
  5848.  
  5849. -  if (hd_irq_handler)
  5850. -/*    hd_irq_handler = unexpected_hd_interrupt;*/
  5851. +  if (!hd_irq_handler)
  5852. +    hd_irq_handler = unexpected_hd_interrupt;
  5853.      hd_irq_handler ();
  5854.  
  5855.    return;
  5856. -  } 
  5857.  }
  5858.  
  5859.  /*te******************************************************************
  5860. @@ -671,12 +663,9 @@
  5861.    /* Test, if ready to read */
  5862.    for (i=0; i<HD_ID_RETRIES; i++)
  5863.      {
  5864. -    if ((inb_p(HD_STATUS) & (DRQ_STAT|READY_STAT)) == (DRQ_STAT|READY_STAT)) /* ++hn: Detect Seagate drives properly */
  5865. +    if (inb_p (HD_STATUS) & DRQ_STAT)
  5866.        {
  5867.        drive_found = 1;
  5868. -#ifdef DEBUG
  5869. -      printk("hd%d: WIN_IDENTIFY: status = 0x%hx\n", drive, inb_p(HD_STATUS));
  5870. -#endif
  5871.        break;
  5872.        }
  5873.      }
  5874. @@ -693,31 +682,26 @@
  5875.      hd_info[drive].sect   = Identify [6];
  5876.      NR_HD++;
  5877.      Identify [47] = 0x0000;
  5878. -    printk ("hd%c: %s\n", (char)drive+'a', (unsigned char *)&Identify [27]); /* ++hn: use hda/hdb naming for the user-messages  */
  5879. +    printk ("hd%d: %s\n", drive, (unsigned char *)&Identify [27]);
  5880.      printk ("     cyl %d, sector %d, head %d.\n",
  5881.                                               hd_info[drive].cyl,
  5882.                                               hd_info[drive].sect,
  5883.                                               hd_info[drive].head);
  5884.      }
  5885.    else
  5886. -    printk ("hd%c not found.\n", (char)drive+'a'); /* ++hn: use hda/hdb naming for the user-messages */
  5887. +    printk ("hd%d not found.\n", drive);
  5888.    }
  5889.  sti ();                             /* Enable interrupts */
  5890.  
  5891.  /* Add the interrupt handler */
  5892.  if (NR_HD)
  5893. -{
  5894. -  if (!add_isr (IRQ_MFP_FDC, hd_interrupt, 0, NULL))
  5895. +/*  if (!add_isr (IRQ_MFP_FDC, hd_interrupt, 0, NULL))
  5896.      {
  5897.      printk ("HD: Can't add interrupt handler for harddisk device.\n");
  5898.      NR_HD = 0;
  5899. -    }
  5900. -  else
  5901. -    {
  5902. +    } */
  5903.      mfp.int_en_b |= 0x80;    /* enable int */
  5904.      mfp.int_mk_b |= 0x80;    /* not masked */
  5905. -    }
  5906. -}
  5907.  
  5908.  i = NR_HD;
  5909.  while (i-- > 0)
  5910. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/drivers/block/ll_rw_blk.c linux-0.9pl4/drivers/block/ll_rw_blk.c
  5911. --- linux-0.9pl3/drivers/block/ll_rw_blk.c    Sun Aug 14 10:30:43 1994
  5912. +++ linux-0.9pl4/drivers/block/ll_rw_blk.c    Mon Nov  7 22:15:16 1994
  5913. @@ -29,6 +29,14 @@
  5914.  extern u_long sbpcd_init(u_long, u_long);
  5915.  #endif CONFIG_SBPCD
  5916.  
  5917. +#ifdef CONFIG_ATARI_ACSI
  5918. +extern u_long acsi_init(u_long, u_long);
  5919. +#endif CONFIG_ATARI_ACSI
  5920. +
  5921. +#ifdef CONFIG_ATARI
  5922. +#include <linux/atarihw.h>    /* for atari_stram_alloc() */
  5923. +#endif
  5924. +
  5925.  /*
  5926.   * The request-struct contains all necessary data
  5927.   * to load a nr of sectors into memory
  5928. @@ -234,16 +242,16 @@
  5929.   * they start processing an entry.  For this reason it is safe to continue
  5930.   * to add links to the top entry for scsi devices.
  5931.   */
  5932. -    if ((major == HD_MAJOR
  5933. +    if ((major == HD_MAJOR || major == ACSI_MAJOR
  5934.           || major == SCSI_DISK_MAJOR
  5935.           || major == SCSI_CDROM_MAJOR)
  5936.          && (req = blk_dev[major].current_request))
  5937.      {
  5938. -            if (major == HD_MAJOR)
  5939. +            if (major == HD_MAJOR || major == ACSI_MAJOR)
  5940.              req = req->next;
  5941.          while (req) {
  5942.              if (req->dev == bh->b_dev &&
  5943. -                !req->waiting &&
  5944. +                !req->sem &&
  5945.                  req->cmd == rw &&
  5946.                  req->sector + req->nr_sectors == sector &&
  5947.                  req->nr_sectors < 254)
  5948. @@ -257,7 +265,7 @@
  5949.              }
  5950.  
  5951.              if (req->dev == bh->b_dev &&
  5952. -                !req->waiting &&
  5953. +                !req->sem &&
  5954.                  req->cmd == rw &&
  5955.                  req->sector - count == sector &&
  5956.                  req->nr_sectors < 254)
  5957. @@ -302,7 +310,7 @@
  5958.      req->nr_sectors = count;
  5959.      req->current_nr_sectors = count;
  5960.      req->buffer = bh->b_data;
  5961. -    req->waiting = NULL;
  5962. +    req->sem = NULL;
  5963.      req->bh = bh;
  5964.      req->bhtail = bh;
  5965.      req->next = NULL;
  5966. @@ -313,6 +321,7 @@
  5967.  {
  5968.      struct request * req;
  5969.      unsigned int major = MAJOR(dev);
  5970. +    struct semaphore sem = MUTEX_LOCKED;
  5971.  
  5972.      if (major >= MAX_BLKDEV || !(blk_dev[major].request_fn)) {
  5973.          printk("Trying to read nonexistent block-device %04x (%d)\n",dev,page*8);
  5974. @@ -334,12 +343,11 @@
  5975.      req->nr_sectors = 8;
  5976.      req->current_nr_sectors = 8;
  5977.      req->buffer = buffer;
  5978. -    req->waiting = current;
  5979. +    req->sem = &sem;
  5980.      req->bh = NULL;
  5981.      req->next = NULL;
  5982. -    current->state = TASK_SWAPPING;
  5983.      add_request(major+blk_dev,req);
  5984. -    schedule();
  5985. +    down(&sem);
  5986.  }
  5987.  
  5988.  /* This function can be used to request a number of buffers from a block
  5989. @@ -441,6 +449,7 @@
  5990.      int buffersize;
  5991.      struct request * req;
  5992.      unsigned int major = MAJOR(dev);
  5993. +    struct semaphore sem = MUTEX_LOCKED;
  5994.  
  5995.      if (major >= MAX_BLKDEV || !(blk_dev[major].request_fn)) {
  5996.          printk("ll_rw_swap_file: trying to swap nonexistent block-device\n");
  5997. @@ -469,12 +478,11 @@
  5998.          req->nr_sectors = buffersize >> 9;
  5999.          req->current_nr_sectors = buffersize >> 9;
  6000.          req->buffer = buf;
  6001. -        req->waiting = current;
  6002. +        req->sem = &sem;
  6003.          req->bh = NULL;
  6004.          req->next = NULL;
  6005. -        current->state = TASK_UNINTERRUPTIBLE;
  6006.          add_request(major+blk_dev,req);
  6007. -        schedule();
  6008. +        down(&sem);
  6009.      }
  6010.  }
  6011.  
  6012. @@ -508,7 +516,21 @@
  6013.  #ifdef CONFIG_SBPCD
  6014.      mem_start = sbpcd_init(mem_start, mem_end);
  6015.  #endif CONFIG_SBPCD
  6016. +#ifdef CONFIG_ATARI_ACSI
  6017. +    mem_start = acsi_init(mem_start, mem_end);
  6018. +#endif CONFIG_ATARI_ACSI
  6019.      if (boot_info.ramdisk_size)
  6020.          mem_start += rd_init(mem_start, boot_info.ramdisk_size*1024);
  6021. +#ifdef CONFIG_ATARI
  6022. +    /* ++roman: Call a function of the Atari floppy driver here that
  6023. +     * allocates some ST-Ram buffers, because atari_stram_alloc()
  6024. +     * isn't possible in atari_floppy_init() any more.
  6025. +     */
  6026. +    if (boot_info.machtype == MACH_ATARI) {
  6027. +        extern unsigned long
  6028. +            atari_floppy_alloc_buffers( unsigned long mem_start );
  6029. +        mem_start = atari_floppy_alloc_buffers( mem_start );
  6030. +    }
  6031. +#endif
  6032.      return mem_start;
  6033.  }
  6034. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/drivers/char/atari_SCC.c linux-0.9pl4/drivers/char/atari_SCC.c
  6035. --- linux-0.9pl3/drivers/char/atari_SCC.c    Sun Aug 14 10:30:41 1994
  6036. +++ linux-0.9pl4/drivers/char/atari_SCC.c    Mon Nov 21 18:09:01 1994
  6037. @@ -25,11 +25,11 @@
  6038.  #include <linux/atariints.h>
  6039.  
  6040.  #include "serial.h"
  6041. -#include "atari_MFPser.h"
  6042. +#include "atari_SCC.h"
  6043.  
  6044.  
  6045.  void atari_init_SCC( struct async_struct *info, SERTYPE type,
  6046. -                     int tt_flag, void *ri_addr,
  6047. +                     int channel, void *ri_addr,
  6048.                       unsigned char ri_bitno, unsigned char ri_active )
  6049.  
  6050.  {    
  6051. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/drivers/char/atari_SCC.h linux-0.9pl4/drivers/char/atari_SCC.h
  6052. --- linux-0.9pl3/drivers/char/atari_SCC.h    Sun Sep 25 16:19:40 1994
  6053. +++ linux-0.9pl4/drivers/char/atari_SCC.h    Mon Nov 21 18:09:02 1994
  6054. @@ -314,7 +314,7 @@
  6055.  
  6056.  /***************************** Prototypes *****************************/
  6057.  
  6058. -void atari_init_SCC( struct async_struct *info, SERTYPE type, int tt_flag,
  6059. +void atari_init_SCC( struct async_struct *info, SERTYPE type, int channel,
  6060.                       void *ri_addr, unsigned char ri_bitno, unsigned char
  6061.                       ri_active );
  6062.  
  6063. @@ -337,6 +337,7 @@
  6064.   * I'm not sure, correct me please!), that gives 4 nops for a TT (32
  6065.   * MHz) (2 would be sufficient for the Falcon (16 MHz), but looking at
  6066.   * boot_info.bi_atari.model at runtime takes longer than 2 nop's...)
  6067. + * ++andreas: nop needs only 2 cycles, seven of them are needed.
  6068.   */
  6069.  
  6070.  static __inline__ void scc_reg_delay( void )
  6071. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/drivers/char/atarimouse.c linux-0.9pl4/drivers/char/atarimouse.c
  6072. --- linux-0.9pl3/drivers/char/atarimouse.c    Sun Aug 14 10:30:41 1994
  6073. +++ linux-0.9pl4/drivers/char/atarimouse.c    Mon Nov 21 18:09:02 1994
  6074. @@ -1,6 +1,11 @@
  6075.  /*
  6076.   * Atari Mouse Driver for Linux
  6077.   * by Robert de Vries (robert@and.nl) 19Jul93
  6078. + *
  6079. + * 16 Nov 1994 Andreas Schwab
  6080. + * Compatibility with busmouse
  6081. + * Support for three button mouse (shamelessly stolen from MiNT)
  6082. + * third button wired to one of the joystick directions on joystick 1
  6083.   */
  6084.  
  6085.  #include <linux/sched.h>
  6086. @@ -11,14 +16,21 @@
  6087.  #include <asm/segment.h>
  6088.  
  6089.  static struct mouse_status mouse;
  6090. +int atari_mouse_buttons;
  6091.  
  6092.  void atari_mouse_interrupt(char *buf)
  6093.  {
  6094. +    int buttons;
  6095. +
  6096.  /*    ikbd_mouse_disable(); */
  6097.  
  6098. -    mouse.buttons = buf[0] & 0x3;
  6099. -    mouse.dx = buf[1];
  6100. -    mouse.dy = buf[2];
  6101. +    buttons = ((buf[0] & 1 ? 1 : 0)
  6102. +           | (buf[0] & 2 ? 4 : 0)
  6103. +           | (atari_mouse_buttons & 2));
  6104. +    atari_mouse_buttons = buttons;
  6105. +    mouse.buttons = ~buttons & 7;
  6106. +    mouse.dx += buf[1];
  6107. +    mouse.dy += buf[2];
  6108.      mouse.ready = 1;
  6109.      wake_up_interruptible(&mouse.wait);
  6110.  
  6111. @@ -43,6 +55,10 @@
  6112.      return -EBUSY;
  6113.      mouse.active = 1;
  6114.      mouse.ready = 0;
  6115. +    mouse.dx = mouse.dy = 0;
  6116. +    atari_mouse_buttons = 0;
  6117. +    ikbd_mouse_y0_bot ();
  6118. +    ikbd_mouse_thresh (1, 1);
  6119.      ikbd_mouse_rel_pos();
  6120.      return 0;
  6121.  }
  6122. @@ -54,21 +70,32 @@
  6123.  
  6124.  static int read_mouse(struct inode *inode, struct file *file, char *buffer, int count)
  6125.  {
  6126. -    int i;
  6127. +    int dx, dy, buttons;
  6128.  
  6129.      if (count < 3)
  6130.      return -EINVAL;
  6131.      if (!mouse.ready)
  6132.      return -EAGAIN;
  6133.      /* ikbd_mouse_disable */
  6134. -    put_fs_byte(mouse.buttons, buffer++);
  6135. -    put_fs_byte(mouse.dx, buffer++);
  6136. -    put_fs_byte(mouse.dy, buffer++);
  6137. -    for (i = 3; i < count; i++)
  6138. -    put_fs_byte(0, buffer++);
  6139. +    dx = mouse.dx;
  6140. +    dy = mouse.dy;
  6141. +    buttons = mouse.buttons;
  6142. +    if (dx > 127)
  6143. +      dx = 127;
  6144. +    else if (dx < -128)
  6145. +      dx = -128;
  6146. +    if (dy > 127)
  6147. +      dy = 127;
  6148. +    else if (dy < -128)
  6149. +      dy = -128;
  6150. +    mouse.dx -= dx;
  6151. +    mouse.dy -= dy;
  6152.      mouse.ready = 0;
  6153.      /* ikbd_mouse_rel_pos(); */
  6154. -    return i;
  6155. +    put_fs_byte(buttons | 0x80, buffer++);
  6156. +    put_fs_byte((char) dx, buffer++);
  6157. +    put_fs_byte((char) dy, buffer++);
  6158. +    return 3;
  6159.  }
  6160.  
  6161.  static int mouse_select(struct inode *inode, struct file *file, int sel_type, select_table *wait)
  6162. Binary files linux-0.9pl3/drivers/char/bdflush-1.4.tar.gz and linux-0.9pl4/drivers/char/bdflush-1.4.tar.gz differ
  6163. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/drivers/char/console.c linux-0.9pl4/drivers/char/console.c
  6164. --- linux-0.9pl3/drivers/char/console.c    Sun Aug 14 10:30:40 1994
  6165. +++ linux-0.9pl4/drivers/char/console.c    Mon Nov 21 18:09:03 1994
  6166. @@ -82,7 +82,9 @@
  6167.  static void clear_selection(void);
  6168.  
  6169.  /* Variables for selection control. */
  6170. -#define SEL_BUFFER_SIZE TTY_BUF_SIZE
  6171. +/* The original size (1024) is to small for my console - FN */
  6172. +#define SEL_BUFFER_SIZE 4096
  6173. +/* #define SEL_BUFFER_SIZE TTY_BUF_SIZE */
  6174.  static int sel_cons;
  6175.  static int sel_start = -1;
  6176.  static int sel_end;
  6177. @@ -93,8 +95,7 @@
  6178.  extern void register_console(void (*proc)(const char *));
  6179.  extern void compute_shiftstate(void);
  6180.  
  6181. -static int console_blanked = 0;
  6182. -static int can_do_color = 0;
  6183. +int console_blanked = 0;
  6184.  static int printable = 0;
  6185.  
  6186.  struct condata vc_cons[NR_CONSOLES];
  6187. @@ -105,6 +106,7 @@
  6188.  #define    y        (vc_cons[currcons].vc_y)
  6189.  #define top        (vc_cons[currcons].vc_top)
  6190.  #define bottom        (vc_cons[currcons].vc_bottom)
  6191. +#define pos        (vc_cons[currcons].vc_pos)
  6192.  /*
  6193.   * Arno:
  6194.   * On the 680x0 we could have screens with different sizes (at least
  6195. @@ -112,6 +114,7 @@
  6196.   * of using a global variable like the original PC code.
  6197.   */
  6198.  #define    video_num_columns    (vc_cons[currcons].vc_cols)
  6199. +#define    video_size_row        (vc_cons[currcons].vc_size_row)
  6200.  #define    video_num_lines        (vc_cons[currcons].vc_rows)
  6201.  #define    state        (vc_cons[currcons].vc_state)
  6202.  #define    npar        (vc_cons[currcons].vc_npar)
  6203. @@ -125,6 +128,7 @@
  6204.  #define    G1_charset    (vc_cons[currcons].vc_G1_charset)
  6205.  #define    saved_G0    (vc_cons[currcons].vc_saved_G0)
  6206.  #define    saved_G1    (vc_cons[currcons].vc_saved_G1)
  6207. +#define    video_mem_start    (vc_cons[currcons].vc_video_mem_start)
  6208.  #define    video_erase_char (vc_cons[currcons].vc_video_erase_char)    
  6209.  #define    decscnm        (vc_cons[currcons].vc_decscnm)
  6210.  #define    decom        (vc_cons[currcons].vc_decom)
  6211. @@ -132,6 +136,7 @@
  6212.  #define    deccm        (vc_cons[currcons].vc_deccm)
  6213.  #define    decim        (vc_cons[currcons].vc_decim)
  6214.  #define    need_wrap    (vc_cons[currcons].vc_need_wrap)
  6215. +#define    can_do_color    (vc_cons[currcons].vc_can_do_color)
  6216.  #define    color        (vc_cons[currcons].vc_color)
  6217.  #define    s_color        (vc_cons[currcons].vc_s_color)
  6218.  #define    def_color    (vc_cons[currcons].vc_def_color)
  6219. @@ -281,6 +286,7 @@
  6220.              y = max_y - 1;
  6221.          else
  6222.              y = new_y;
  6223. +    pos = video_mem_start + y * video_num_columns + x;
  6224.      need_wrap = 0;
  6225.  }
  6226.  
  6227. @@ -319,9 +325,22 @@
  6228.  static void scrup(int currcons, unsigned int t, unsigned int b,
  6229.            int nr)
  6230.  {
  6231. +    unsigned short *p;
  6232. +    int i;
  6233. +
  6234.      if (b > video_num_lines || t >= b)
  6235.          return;
  6236.  
  6237. +    memmove (video_mem_start + t * video_num_columns,
  6238. +         video_mem_start + (t + nr) * video_num_columns,
  6239. +         (b - t - nr) * video_num_columns * 2);
  6240. +
  6241. +    p = video_mem_start + (b - nr) * video_num_columns;
  6242. +    for (i = nr * video_num_columns; i > 0; i--)
  6243. +      *p++ = video_erase_char;
  6244. +
  6245. +    if (currcons != fg_console)
  6246. +      return;
  6247.  /*
  6248.   * Arno:
  6249.   * Scrolling has now been moved to amicon.c where it should have
  6250. @@ -336,9 +355,22 @@
  6251.  static void scrdown(int currcons, unsigned int t, unsigned int b,
  6252.              int nr)
  6253.  {
  6254. +    unsigned short *p;
  6255. +    int i;
  6256. +
  6257.      if (b > video_num_lines || t >= b)
  6258.          return;
  6259.  
  6260. +    memmove (video_mem_start + (t + nr) * video_num_columns,
  6261. +         video_mem_start + t * video_num_columns,
  6262. +         (b - t - nr) * video_num_columns * 2);
  6263. +
  6264. +    p = video_mem_start + t * video_num_columns;
  6265. +    for (i = nr * video_num_columns; i > 0; i--)
  6266. +      *p++ = video_erase_char;
  6267. +
  6268. +    if (currcons != fg_console)
  6269. +      return;
  6270.  /*
  6271.   * Arno:
  6272.   * Scrolling has now been moved to amicon.c where it should have
  6273. @@ -353,6 +385,7 @@
  6274.  {
  6275.      if (y+1<bottom) {
  6276.          y++;
  6277. +        pos += video_num_columns;
  6278.          return;
  6279.      } else 
  6280.          scrup(currcons,top,bottom, 1);
  6281. @@ -363,6 +396,7 @@
  6282.  {
  6283.      if (y>top) {
  6284.          y--;
  6285. +        pos -= video_num_columns;
  6286.          return;
  6287.      } else
  6288.          scrdown(currcons,top,bottom, 1);
  6289. @@ -371,12 +405,14 @@
  6290.  
  6291.  static inline void cr(int currcons)
  6292.  {
  6293. +    pos -= x;
  6294.      need_wrap = x = 0;
  6295.  }
  6296.  
  6297.  static inline void bs(int currcons)
  6298.  {
  6299.      if (x) {
  6300. +        pos--;
  6301.          x--;
  6302.          need_wrap = 0;
  6303.      }
  6304. @@ -396,41 +432,77 @@
  6305.  
  6306.  static void csi_J(int currcons, int vpar)
  6307.  {
  6308. +    unsigned long count;
  6309. +    unsigned short *start;
  6310. +
  6311.      switch (vpar) {
  6312.          case 0:    /* erase from cursor to end of display */
  6313. +            count = (video_mem_start
  6314. +                 + video_num_columns * video_num_lines
  6315. +                 - pos);
  6316. +            start = pos;
  6317. +            if (currcons != fg_console)
  6318. +              break;
  6319.              /* 680x0 do in two stages */
  6320.              sw->con_clear(&vc_cons[currcons],y,x,1,video_num_columns-x);
  6321.              sw->con_clear(&vc_cons[currcons],y+1,0,video_num_lines-y-1, video_num_columns);
  6322.              break;
  6323.          case 1:    /* erase from start to cursor */
  6324. +            count = pos - video_mem_start + 1;
  6325. +            start = video_mem_start;
  6326. +            if (currcons != fg_console)
  6327. +              break;
  6328.              /* 680x0 do in two stages */
  6329.              sw->con_clear(&vc_cons[currcons],0,0,y, video_num_columns);
  6330.              sw->con_clear(&vc_cons[currcons],y,0,1,x + 1);
  6331.              break;
  6332.          case 2: /* erase whole display */
  6333. +            count = video_num_columns * video_num_lines;
  6334. +            start = video_mem_start;
  6335. +            if (currcons != fg_console)
  6336. +              break;
  6337.              sw->con_clear(&vc_cons[currcons],0,0,video_num_lines, video_num_columns);
  6338.              break;
  6339.          default:
  6340.              return;
  6341.      }
  6342. +    while (count-- > 0)
  6343. +      *start++ = video_erase_char;
  6344.      need_wrap = 0;
  6345.  }
  6346.  
  6347.  static void csi_K(int currcons, int vpar)
  6348.  {
  6349. +    unsigned long count;
  6350. +    unsigned short *start;
  6351. +
  6352.      switch (vpar) {
  6353.          case 0:    /* erase from cursor to end of line */
  6354. +            count = video_num_columns - x;
  6355. +            start = pos;
  6356. +            if (currcons != fg_console)
  6357. +              break;
  6358.              sw->con_clear(&vc_cons[currcons],y,x,1,video_num_columns-x);
  6359.              break;
  6360.          case 1:    /* erase from start of line to cursor */
  6361. +            start = pos - x;
  6362. +            count = x + 1;
  6363. +            if (currcons != fg_console)
  6364. +              break;
  6365.              sw->con_clear(&vc_cons[currcons],y,0,1,x + 1);
  6366.              break;
  6367.          case 2: /* erase whole line */
  6368. +            start = pos - x;
  6369. +            count = video_num_columns;
  6370. +            if (currcons != fg_console)
  6371. +              break;
  6372.              sw->con_clear(&vc_cons[currcons],y,0,1,video_num_columns);
  6373.              break;
  6374.          default:
  6375.              return;
  6376.      }
  6377. +    while (count-- > 0)
  6378. +      *start++ = video_erase_char;
  6379.      need_wrap = 0;
  6380.  }
  6381.  
  6382. @@ -444,28 +516,39 @@
  6383.   * seems hardware independent, but uses the EGA/VGA way of representing
  6384.   * attributes. 
  6385.   * TODO: modify for 680x0 and add attribute processing to putc code.
  6386. + *
  6387. + * ++roman: I completely changed the attribute format for monochrome
  6388. + * mode (!can_do_color). The formerly used MDA (monochrome display
  6389. + * adapter) format didn't allow the combination of certain effects.
  6390. + * Now the attribute is just a bit vector:
  6391. + *  Bit 0..1: intensity (0..2)
  6392. + *  Bit 2   : underline
  6393. + *  Bit 3   : reverse
  6394. + *  Bit 7   : blink
  6395.   */
  6396.  static void update_attr(int currcons)
  6397.  {
  6398. +    if (!can_do_color) {
  6399. +        /* Special treatment for monochrome */
  6400. +        attr = intensity |
  6401. +            (underline ? 4 : 0) |
  6402. +            ((reverse ^ decscnm) ? 8 : 0) |
  6403. +            (blink ? 0x80 : 0);
  6404. +        video_erase_char = ' ' | ((reverse ^ decscnm) ? 0x800 : 0);
  6405. +        return;
  6406. +    }
  6407. +
  6408.      attr = color;
  6409. -    if (can_do_color) {
  6410.          if (underline)
  6411.              attr = (attr & 0xf0) | ulcolor;
  6412.          else if (intensity == 0)
  6413.              attr = (attr & 0xf0) | halfcolor;
  6414. -    }
  6415.      if (reverse ^ decscnm)
  6416.          attr = (attr & 0x88) | (((attr >> 4) | (attr << 4)) & 0x77);
  6417.      if (blink)
  6418.          attr ^= 0x80;
  6419.      if (intensity == 2)
  6420.          attr ^= 0x08;
  6421. -    if (!can_do_color) {
  6422. -        if (underline)
  6423. -            attr = (attr & 0xf8) | 0x01;
  6424. -        else if (intensity == 0)
  6425. -            attr = (attr & 0xf0) | 0x08;
  6426. -    }
  6427.      if (decscnm)
  6428.          video_erase_char = (((color & 0x88) | (((color >> 4) | (color << 4)) & 0x77)) << 8) | ' ';
  6429.      else
  6430. @@ -676,6 +759,17 @@
  6431.  
  6432.  static void insert_char(int currcons)
  6433.  {
  6434. +    int i;
  6435. +    unsigned short *p = pos;
  6436. +
  6437. +    for (i = video_num_columns - x - 2; i >= 0; i--)
  6438. +      p[i + 1] = p[i];
  6439. +    *pos = video_erase_char;
  6440. +    need_wrap = 0;
  6441. +
  6442. +    if (currcons != fg_console)
  6443. +      return;
  6444. +
  6445.      /* Arno:
  6446.       * Move the remainder of the line (-1 character) one spot to the right
  6447.       */
  6448. @@ -683,23 +777,34 @@
  6449.      /*
  6450.       * Print the erase char on the current position
  6451.       */
  6452. -    sw->con_putc(&vc_cons[currcons],(video_erase_char & 0x00ff),y,x,reverse ? DM_INVERSE : DM_COPY);
  6453. -
  6454. -    need_wrap = 0;
  6455. +    sw->con_putc(&vc_cons[currcons],(video_erase_char & 0x00ff),y,x);
  6456.  }
  6457.  
  6458.  static void csi_at(int currcons, unsigned int nr)
  6459.  {
  6460. +    int i;
  6461. +    unsigned short *p;
  6462. +
  6463.      if (nr > video_num_columns - x)
  6464.          nr = video_num_columns - x;
  6465.      else if (!nr)
  6466.          nr = 1;
  6467. +
  6468. +    p = pos + video_num_columns - x - nr;
  6469. +    while (--p >= pos)
  6470. +      p[nr] = *p;
  6471. +    for (i = 0; i < nr; i++)
  6472. +      *++p = video_erase_char;
  6473. +    need_wrap = 0;
  6474. +
  6475. +    if (currcons != fg_console)
  6476. +      return;
  6477. +
  6478.      sw->con_bmove (&vc_cons[currcons], y, x, y, x + nr,
  6479.                 1, video_num_columns - x - nr);
  6480.      while (nr--)
  6481.        sw->con_putc (&vc_cons[currcons], video_erase_char & 0x00ff,
  6482. -            y, x + nr, reverse ? DM_INVERSE : DM_COPY);
  6483. -    need_wrap = 0;
  6484. +            y, x + nr);
  6485.  }
  6486.  
  6487.  static void csi_L(int currcons, unsigned int nr)
  6488. @@ -714,20 +819,31 @@
  6489.  
  6490.  static void csi_P(int currcons, unsigned int nr)
  6491.  {
  6492. +    int i;
  6493. +    unsigned short *p, *end;
  6494. +
  6495.      if (nr > video_num_columns - x)
  6496.          nr = video_num_columns - x;
  6497.      else if (!nr)
  6498.          nr = 1;
  6499.  
  6500. +    p = pos;
  6501. +    end = pos + video_num_columns - x - nr;
  6502. +    while (p < end)
  6503. +      *p = p[nr], p++;
  6504. +    for (i = 0; i < nr; i++)
  6505. +      *p++ = video_erase_char;
  6506. +    need_wrap = 0;
  6507. +
  6508. +    if (currcons != fg_console)
  6509. +      return;
  6510. +
  6511.      sw->con_bmove (&vc_cons[currcons], y, x + nr, y, x,
  6512.                 1, video_num_columns - x - nr);
  6513.  
  6514.      while (nr--)
  6515.        sw->con_putc (&vc_cons[currcons], video_erase_char & 0x00ff,
  6516. -            y, video_num_columns - 1 - nr, reverse ? DM_INVERSE
  6517. -            : DM_COPY);
  6518. -
  6519. -    need_wrap = 0;
  6520. +            y, video_num_columns - 1 - nr);
  6521.  }
  6522.  
  6523.  static void csi_M(int currcons, unsigned int nr)
  6524. @@ -829,6 +945,11 @@
  6525.          printk("con_write: illegal tty (%d)\n", currcons);
  6526.          return;
  6527.      }
  6528. +
  6529. +    /* undraw cursor first */
  6530. +    if (currcons == fg_console)
  6531. +        hide_cursor(currcons);
  6532. +
  6533.  #ifdef CONFIG_SELECTION
  6534.      /* clear the selection as soon as any characters are to be written
  6535.         out on the console holding the selection. */
  6536. @@ -854,18 +975,22 @@
  6537.                           * P.S. I hate 8 spaces per tab! Use Emacs!
  6538.                          */
  6539.  
  6540. -                        if (!decim) { 
  6541. +            /* Only use this for the foreground console,
  6542. +                           where we really draw the chars */
  6543. +
  6544. +                        if (!decim && currcons == fg_console) { 
  6545.                              char   *p     = buf;
  6546.                              ushort count  = 1;
  6547.                              ushort nextx  = x + 1;
  6548.                              ushort cols   = video_num_columns;
  6549.                              
  6550. -                            *p++ = c;
  6551. +                            *p++ = translate[c];
  6552. +                *pos++ = translate[c] | (attr << 8);
  6553.  
  6554.                              if (nextx == cols) {
  6555.                                  sw->con_putc(&vc_cons[currcons],
  6556. -                                             *buf, y, x, reverse ? DM_INVERSE
  6557. -                         : DM_COPY);
  6558. +                                             *buf, y, x);
  6559. +                pos--;
  6560.                                  need_wrap = decawm;
  6561.                                  continue;
  6562.                              }
  6563. @@ -876,7 +1001,8 @@
  6564.                     (c=get_tty_queue(&tty->write_q)) >= 0 &&
  6565.                                     translate[c])
  6566.                  {
  6567. -                                *p++ = c;
  6568. +                                *p++ = translate[c];
  6569. +                *pos++ = translate[c] | (attr << 8);
  6570.                  ++count;
  6571.                  ++nextx;
  6572.                  if (nextx == cols || count == sizeof (buf))
  6573. @@ -884,9 +1010,9 @@
  6574.                  }
  6575.  
  6576.                              sw->con_putcs(&vc_cons[currcons],
  6577. -                                          buf, count, y, x, reverse ? DM_INVERSE
  6578. -                      : DM_COPY);
  6579. +                                          buf, count, y, x);
  6580.                              if (nextx == cols) {
  6581. +                    pos--;
  6582.                                  x         = cols-1;
  6583.                                  need_wrap = decawm;
  6584.                  continue;
  6585. @@ -907,17 +1033,19 @@
  6586.               * TODO: build VT100 charset and enable translation.
  6587.               */
  6588.  
  6589. -            /*c = translate[c];*/
  6590. +            c = translate[c];
  6591.  
  6592.              /* Arno:
  6593.               * 680x0: ignore attributes for now, just 
  6594.               * print character.
  6595.               */
  6596. -            sw->con_putc(&vc_cons[currcons],c,y,x,
  6597. -                     reverse ? DM_INVERSE : DM_COPY);
  6598. +            *pos = c | (attr << 8);
  6599. +            if (currcons == fg_console)
  6600. +              sw->con_putc(&vc_cons[currcons],c,y,x);
  6601.              if (x == video_num_columns - 1)
  6602.                  need_wrap = decawm;
  6603.              else {
  6604. +                pos++;
  6605.                  x++;
  6606.              }
  6607.              continue;
  6608. @@ -935,11 +1063,13 @@
  6609.                  bs(currcons);
  6610.                  continue;
  6611.              case 9:
  6612. +                pos -= x;
  6613.                  while (x < video_num_columns - 1) {
  6614.                      x++;
  6615.                      if (tab_stop[x >> 5] & (1 << (x & 31)))
  6616.                          break;
  6617.                  }
  6618. +                pos += x;
  6619.                  continue;
  6620.              case 10: case 11: case 12:
  6621.                  lf(currcons);
  6622. @@ -1242,6 +1372,10 @@
  6623.     if (!printable || currcons<0 || currcons>=NR_CONSOLES)
  6624.        return;
  6625.  
  6626. +    /* undraw cursor first */
  6627. +    if (currcons == fg_console)
  6628. +        hide_cursor(currcons);
  6629. +
  6630.     /* Contrived structure to try and emulate original need_wrap behaviour
  6631.      * Problems caused when we have need_wrap set on '\n' character */
  6632.     
  6633. @@ -1249,8 +1383,10 @@
  6634.         if (c == 10 || c == 13 || need_wrap) {
  6635.             if ((count = b - start - 1) > 0) {
  6636.                 sw->con_putcs(&vc_cons[currcons], start, count ,
  6637. -                             y, x, DM_COPY);
  6638. +                             y, x);
  6639.                 x += count;
  6640. +           if (need_wrap)
  6641. +         x--;
  6642.             }
  6643.  
  6644.             if (c != 13)
  6645. @@ -1264,16 +1400,18 @@
  6646.             start = b-1; myx = x;
  6647.         }
  6648.  
  6649. +       *pos = c | (attr << 8);
  6650.         if (myx == video_num_columns - 1) {
  6651.             need_wrap = 1;
  6652.             continue;
  6653.         }
  6654. +       pos++;
  6655.         myx++;
  6656.     }
  6657.  
  6658.     if ((count = b - start -1) > 0) {
  6659.         sw->con_putcs(&vc_cons[currcons], start, count ,
  6660. -                     y, x, DM_COPY);
  6661. +                     y, x);
  6662.         x += count;
  6663.         if (x == video_num_columns)
  6664.       {
  6665. @@ -1301,14 +1439,6 @@
  6666.      char *display_desc = "????";
  6667.      unsigned int currcons = 0;
  6668.  
  6669. -/* 
  6670. - * Arno:
  6671. - * We really should move this to sw->con_init or some other platform
  6672. - * specific init code instead of hard-coding this...
  6673. - */
  6674. -    display_desc="ECS";
  6675. -    can_do_color=1;
  6676. -
  6677.      sw=conswitchp;
  6678.      timer_table[BLANK_TIMER].fn = blank_screen;
  6679.      timer_table[BLANK_TIMER].expires = 0;
  6680. @@ -1316,17 +1446,7 @@
  6681.          timer_table[BLANK_TIMER].expires = jiffies+blankinterval;
  6682.          timer_active |= 1<<BLANK_TIMER;
  6683.      }
  6684. -    kmem_start = sw->con_init(&vc_cons[currcons], kmem_start);
  6685.  
  6686. -#if 0
  6687. -/* 
  6688. - * Arno:
  6689. - * Strange things happen when more than 1 console is inited... 
  6690. - * 
  6691. - * TODO: extend low-level code for multi-console support.
  6692. - * Question: how are we going to do VC's? Save/restore bitplanes/copperlists
  6693. - * etc.? Can get memory expensive with 4 bitplane screens (in the future..)
  6694. - */
  6695.      for (currcons = 0; currcons<NR_CONSOLES; currcons++) {
  6696.          vcmode        = KD_TEXT;
  6697.          vtmode.mode    = VT_AUTO;
  6698. @@ -1337,22 +1457,20 @@
  6699.          vtpid        = -1;
  6700.          vtnewvt        = -1;
  6701.          clr_kbd(kbdraw);
  6702. +        sw = conswitchp;
  6703. +        can_do_color = 1;
  6704. +        kmem_start = sw->con_init(&vc_cons[currcons], kmem_start, &display_desc);
  6705. +        video_size_row = video_num_columns * 2;
  6706. +        pos = video_mem_start = (unsigned short *) kmem_start;
  6707. +        kmem_start += video_num_columns * video_num_lines * 2;
  6708.          def_color    = 0x07;   /* white */
  6709.          ulcolor        = 0x0f;   /* bold white */
  6710.          halfcolor    = 0x08;   /* grey */
  6711. -        reset_terminal(currcons, currcons);
  6712. -
  6713. -
  6714. +        reset_terminal(currcons, 1);
  6715.      }
  6716. -#endif
  6717. -
  6718.  
  6719. +    vcmode = KD_TEXT;
  6720.      currcons = fg_console = 0;
  6721. -    def_color    = 0x07;   /* white */
  6722. -    ulcolor        = 0x0f;   /* bold white */
  6723. -    halfcolor    = 0x08;   /* grey */
  6724. -    reset_terminal(currcons, currcons);
  6725. -
  6726.      gotoxy(currcons,0,0);
  6727.      save_cur(currcons);
  6728.      gotoxy(currcons,0,0);
  6729. @@ -1365,7 +1483,7 @@
  6730.      register_console(console_print);
  6731.  
  6732.      printk("Console: %s %s %ldx%ld, %d virtual consoles\n",
  6733. -        can_do_color?"colour":"mono",
  6734. +        can_do_color ? "colour":"mono",
  6735.          display_desc,
  6736.          video_num_columns,video_num_lines,
  6737.          NR_CONSOLES);
  6738. @@ -1400,54 +1518,87 @@
  6739.          timer_active |= 1<<BLANK_TIMER;
  6740.      }
  6741.      console_blanked = 0;
  6742. -        (vc_cons[fg_console].vc_sw)->con_blank (0);
  6743. +    if ((vc_cons[fg_console].vc_sw)->con_blank (0))
  6744. +        /* Low-level driver cannot restore -> do it ourselves */
  6745. +          update_screen( fg_console );
  6746. +    set_cursor (fg_console);
  6747.  }
  6748.  
  6749.  void update_screen(int new_console)
  6750.  {
  6751. +    int currcons = fg_console;
  6752. +    int xx, yy, startx, attr_save;
  6753. +    char buf[256], *bufp;
  6754. +    unsigned short *p;
  6755.      static int lock = 0;
  6756.  
  6757. -    if (new_console == fg_console || lock)
  6758. -        return;
  6759. +    if (/* new_console == fg_console || */ lock)
  6760.      return;
  6761.      lock = 1;
  6762. -    fg_console = new_console;
  6763.      kbdsave(new_console);
  6764. -#if 0
  6765. -    get_scrmem(fg_console); 
  6766. -    set_scrmem(fg_console); 
  6767. -    set_origin(fg_console);
  6768. -    set_cursor(new_console);
  6769. +    sw->con_cursor (&vc_cons[currcons], CM_ERASE);
  6770. +    sw->con_switch (&vc_cons[new_console]);
  6771. +    currcons = fg_console = new_console;
  6772. +    /* Update the screen contents */
  6773. +    p = video_mem_start;
  6774. +    attr_save = attr;
  6775. +    for (yy = 0; yy < video_num_lines; yy++)
  6776. +      {
  6777. +        bufp = buf;
  6778. +        for (startx = xx = 0; xx < video_num_columns; xx++)
  6779. +          {
  6780. +        if (attr != (*p >> 8) & 0xff)
  6781. +          {
  6782. +            if (bufp > buf)
  6783. +              sw->con_putcs (&vc_cons[currcons], buf, bufp - buf,
  6784. +                     yy, startx);
  6785. +            startx = xx;
  6786. +            bufp = buf;
  6787. +            attr = (*p >> 8) & 0xff;
  6788. +          }
  6789. +        *bufp++ = *p++;
  6790. +        if (bufp == buf + sizeof (buf))
  6791. +          {
  6792. +            sw->con_putcs (&vc_cons[currcons], buf, bufp - buf,
  6793. +                   yy, startx);
  6794. +            startx = xx + 1;
  6795. +            bufp = buf;
  6796. +          }
  6797. +          }
  6798. +        if (bufp > buf)
  6799. +          sw->con_putcs (&vc_cons[currcons], buf, bufp - buf,
  6800. +                 yy, startx);
  6801. +      }
  6802. +    set_cursor (currcons);
  6803. +    attr = attr_save;
  6804.      set_leds();
  6805.      compute_shiftstate();
  6806. -#endif
  6807.      lock = 0;
  6808.  }
  6809.  
  6810.  int do_screendump(int arg)
  6811.  {
  6812. -#if 0
  6813.      char *sptr, *buf = (char *)arg;
  6814.      int currcons, l;
  6815.  
  6816.      if (!suser())
  6817.          return -EPERM;
  6818. -    l = verify_area(VERIFY_WRITE, buf,2+video_num_columns*video_num_lines);
  6819. +    l = verify_area(VERIFY_READ, buf,2);
  6820.      if (l)
  6821.          return l;
  6822.      currcons = get_fs_byte(buf+1);
  6823.      if ((currcons<0) || (currcons>NR_CONSOLES))
  6824.          return -EIO;
  6825. +    currcons = (currcons ? currcons-1 : fg_console);
  6826. +    l = verify_area(VERIFY_WRITE, buf,2+video_num_columns*video_num_lines);
  6827. +    if (l)
  6828. +        return l;
  6829.      put_fs_byte((char)(video_num_lines),buf++);    
  6830.      put_fs_byte((char)(video_num_columns),buf++);
  6831. -    currcons = (currcons ? currcons-1 : fg_console);
  6832. -    sptr = (char *) origin;
  6833. +    sptr = (char *) video_mem_start;
  6834.      for (l=video_num_lines*video_num_columns; l>0 ; l--, sptr++)
  6835.          put_fs_byte(*sptr++,buf++);    
  6836.      return(0);
  6837. -#else
  6838. -        return -EOPNOTSUPP;
  6839. -#endif
  6840.  }
  6841.  
  6842.  /*
  6843. @@ -1468,24 +1619,45 @@
  6844.  }
  6845.  
  6846.  #ifdef CONFIG_SELECTION
  6847. -/* correction factor for when screen is hardware-scrolled */
  6848. -#define    hwscroll_offset (currcons == fg_console ? ((__real_origin - __origin) << 1) : 0)
  6849.  
  6850.  /* set reverse video on characters s-e of console with selection. */
  6851.  static void highlight(const int currcons, const int s, const int e)
  6852.  {
  6853. -    unsigned char *p, *p1, *p2;
  6854. +    int xpos, ypos, k, start, end;
  6855. +    int oldattr, chattr;
  6856. +    unsigned short *p;
  6857.  
  6858. -    p1 = (unsigned char *)origin - hwscroll_offset + s + 1;
  6859. -    p2 = (unsigned char *)origin - hwscroll_offset + e + 1;
  6860. -    if (p1 > p2)
  6861. +    if (s < e)
  6862.      {
  6863. -        p = p1;
  6864. -        p1 = p2;
  6865. -        p2 = p;
  6866. +        start = s >> 1;
  6867. +        end = e >> 1;
  6868.      }
  6869. -    for (p = p1; p <= p2; p += 2)
  6870. -        *p = (*p & 0x88) | ((*p << 4) & 0x70) | ((*p >> 4) & 0x07);
  6871. +    else
  6872. +    {
  6873. +        start = e >> 1;
  6874. +        end = s >> 1;
  6875. +    }
  6876. +    oldattr = attr;
  6877. +
  6878. +    for (k = start; k <= end; k++)
  6879. +    {
  6880. +        ypos = k / video_num_columns;
  6881. +        xpos = k - (ypos * video_num_columns);
  6882. +        p = video_mem_start + k;
  6883. +        chattr = (*p >> 8) & 0xff;
  6884. +
  6885. +        if (can_do_color)
  6886. +          attr = ((chattr << 4) & 0x70) | ((chattr >> 4) & 0x07);
  6887. +        else
  6888. +          attr = chattr | 8;
  6889. +          
  6890. +        /* invert the character on screen */
  6891. +        sw->con_putc(&vc_cons[currcons], *p & 0xff, ypos, xpos);
  6892. +        /* dunno if this might break with VCs - directly modifying the VC buffers */
  6893. +        /* write the (inverted) character into the VC buffer also */
  6894. +        *p = ((*p & 0xff) | (attr << 8));
  6895. +    }
  6896. +    attr = oldattr;
  6897.  }
  6898.  
  6899.  /* is c in range [a-zA-Z0-9_]? */
  6900. @@ -1494,6 +1666,7 @@
  6901.  /* does screen address p correspond to character at LH/RH edge of screen? */
  6902.  static inline int atedge(const int p)
  6903.  {
  6904. +    int currcons = fg_console;
  6905.      return (!(p % video_size_row) || !((p + 2) % video_size_row));
  6906.  }
  6907.  
  6908. @@ -1511,7 +1684,12 @@
  6909.      int sel_mode, new_sel_start, new_sel_end, spc;
  6910.      char *bp, *obp, *spos;
  6911.      int i, ps, pe;
  6912. -    char *off = (char *)origin - hwscroll_offset;
  6913. +
  6914. +    /* 
  6915. +        off is video_mem_start + 1 because the lower byte of a short in 
  6916. +        the buffer contains the character 
  6917. +    */
  6918. +    char *off = (char *)video_mem_start + 1;
  6919.  
  6920.      unblank_screen();
  6921.      args = (unsigned short *)(arg + 1);
  6922. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/drivers/char/lp.c linux-0.9pl4/drivers/char/lp.c
  6923. --- linux-0.9pl3/drivers/char/lp.c    Sun Aug 14 10:30:39 1994
  6924. +++ linux-0.9pl4/drivers/char/lp.c    Thu Nov 24 21:01:35 1994
  6925. @@ -138,7 +138,7 @@
  6926.  static int lp_write_interrupt(struct inode * inode, struct file * file, char * buf, int count)
  6927.  #endif
  6928.  {
  6929. -    static unsigned long total_bytes_written = 0;
  6930. +    unsigned long total_bytes_written = 0;
  6931.  
  6932.      do {
  6933.          bytes_written = 0;
  6934. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/drivers/char/mem.c linux-0.9pl4/drivers/char/mem.c
  6935. --- linux-0.9pl3/drivers/char/mem.c    Tue Sep 27 22:24:36 1994
  6936. +++ linux-0.9pl4/drivers/char/mem.c    Sun Oct 23 15:34:29 1994
  6937. @@ -94,12 +94,13 @@
  6938.  {
  6939.      struct vm_area_struct * mpnt;
  6940.  
  6941. -    if (off & 0xfff || off + len < off)
  6942. +    if ((off & 0xfff) || off + len < off)
  6943.          return -ENXIO;
  6944.  #ifdef __i386__
  6945.      if (x86 > 3 && off >= high_memory)
  6946.          prot |= PAGE_PCD;
  6947.  #endif
  6948. +
  6949.      if (remap_page_range(addr, off, len, prot))
  6950.          return -EAGAIN;
  6951.  /* try to create a dummy vmm-structure so that the rest of the kernel knows we are here */
  6952. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/drivers/char/serial.c linux-0.9pl4/drivers/char/serial.c
  6953. --- linux-0.9pl3/drivers/char/serial.c    Mon Sep 19 21:39:39 1994
  6954. +++ linux-0.9pl4/drivers/char/serial.c    Mon Nov 21 18:09:04 1994
  6955. @@ -215,7 +215,7 @@
  6956.      save_flags(flags); cli();
  6957.  
  6958.  #ifdef SERIAL_DEBUG_OPEN
  6959. -    printk("starting up ttyS%d ...", info->line);
  6960. +    printk("starting up ttyS%d\n", info->line);
  6961.  #endif
  6962.  
  6963.      info->sw->init( info );
  6964. @@ -247,7 +247,7 @@
  6965.          return;
  6966.  
  6967.  #ifdef SERIAL_DEBUG_OPEN
  6968. -    printk("Shutting down serial port %d ....", info->line);
  6969. +    printk("Shutting down serial port %d\n", info->line);
  6970.  #endif
  6971.      
  6972.      save_flags(flags); cli(); /* Disable interrupts */
  6973. @@ -873,7 +873,7 @@
  6974.      info->pgrp = current->pgrp;
  6975.  
  6976.  #ifdef SERIAL_DEBUG_OPEN
  6977. -    printk("rs_open ttyS%d successfull...", info->line);
  6978. +    printk("rs_open ttyS%d successfull\n", info->line);
  6979.  #endif
  6980.      return 0;
  6981.  }
  6982. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/drivers/char/tty_io.c linux-0.9pl4/drivers/char/tty_io.c
  6983. --- linux-0.9pl3/drivers/char/tty_io.c    Mon Sep 19 21:29:37 1994
  6984. +++ linux-0.9pl4/drivers/char/tty_io.c    Thu Oct 20 22:54:22 1994
  6985. @@ -778,7 +778,9 @@
  6986.              }
  6987.              if (tty->char_error == TTY_OVERRUN) {
  6988.                  tty->char_error = 0;
  6989. +#if 0 /* XXX */
  6990.                  printk("tty%d: input overrun\n", tty->line);
  6991. +#endif
  6992.                  continue;
  6993.              }
  6994.              /* Must be a parity or frame error */
  6995. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/drivers/net/slip.c linux-0.9pl4/drivers/net/slip.c
  6996. --- linux-0.9pl3/drivers/net/slip.c    Sun Mar 13 08:47:58 1994
  6997. +++ linux-0.9pl4/drivers/net/slip.c    Mon Oct 10 16:47:47 1994
  6998. @@ -1102,9 +1102,9 @@
  6999.    DPRINTF((DBG_SLIP, "SLIP: ioctl(%d, 0x%X, 0x%X)\n", tty->line, cmd, arg));
  7000.    switch(cmd) {
  7001.      case SIOCGIFNAME:
  7002. -        err=verify_area(VERIFY_WRITE, arg, 16);
  7003. +        err=verify_area(VERIFY_WRITE, arg, strlen(sl->dev->name) + 1);
  7004.          if(err)
  7005. -            return -err;
  7006. +            return err;
  7007.          memcpy_tofs(arg, sl->dev->name, strlen(sl->dev->name) + 1);
  7008.          return(0);
  7009.      case SIOCGIFENCAP:
  7010. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/drivers/scsi/Makefile linux-0.9pl4/drivers/scsi/Makefile
  7011. --- linux-0.9pl3/drivers/scsi/Makefile    Sun Aug 14 10:30:46 1994
  7012. +++ linux-0.9pl4/drivers/scsi/Makefile    Mon Nov  7 22:25:08 1994
  7013. @@ -82,8 +82,8 @@
  7014.  endif
  7015.  
  7016.  ifdef CONFIG_ATARI_SCSI
  7017. -SCSI_OBJS := $(SCSI_OBJS) atari_sc.o
  7018. -SCSI_SRCS := $(SCSI_SRCS) atari_sc.c
  7019. +SCSI_OBJS := $(SCSI_OBJS) atari_scsi.o
  7020. +SCSI_SRCS := $(SCSI_SRCS) atari_scsi.c
  7021.  endif
  7022.    
  7023.  scsi.a: $(SCSI_OBJS)
  7024. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/drivers/scsi/atari_NCR5380.c linux-0.9pl4/drivers/scsi/atari_NCR5380.c
  7025. --- linux-0.9pl3/drivers/scsi/atari_NCR5380.c    Tue Sep 27 22:22:09 1994
  7026. +++ linux-0.9pl4/drivers/scsi/atari_NCR5380.c    Thu Nov 24 21:09:40 1994
  7027. @@ -59,7 +59,10 @@
  7028.  
  7029.  
  7030.  /*
  7031. - * $Log: NCR5380.c,v $
  7032. + * $Log: atari_NCR5380.c,v $
  7033. + * Revision 1.1  1994/11/08  03:25:43  hamish
  7034. + * Initial revision
  7035. + *
  7036.   * Revision 1.5  1994/01/19  09:14:57  drew
  7037.   * Fixed udelay() hack that was being used on DATAOUT phases
  7038.   * instead of a propper wait for the final handshake.
  7039. @@ -837,6 +840,7 @@
  7040.      NCR5380_all_init();
  7041.  
  7042.      hostdata->id_mask = 1 << instance->this_id;
  7043. +    hostdata->id_higher_mask = 0;
  7044.      for (i = hostdata->id_mask; i <= 0x80; i <<= 1)
  7045.      if (i > hostdata->id_mask)
  7046.          hostdata->id_higher_mask |= i;
  7047. @@ -1003,7 +1007,7 @@
  7048.           */
  7049.          for (tmp = (Scsi_Cmnd *) hostdata->issue_queue, 
  7050.              prev = NULL; tmp; prev = tmp, tmp = (Scsi_Cmnd *) 
  7051. -            tmp->host_scribble) 
  7052. +            tmp->host_scribble) {
  7053.  
  7054.              /*  When we find one, remove it from the issue queue. */
  7055.              if (!(hostdata->busy[tmp->target] & (1 << tmp->lun))) {
  7056. @@ -1044,12 +1048,15 @@
  7057.                  hostdata->issue_queue;
  7058.                  hostdata->issue_queue = tmp;
  7059.                  sti();
  7060. +                if (hostdata->connected)
  7061. +                break;
  7062.  #if (NDEBUG & (NDEBUG_MAIN | NDEBUG_QUEUES))
  7063.              printk("scsi%d : main(): select() failed, returned to issue_queue\n",
  7064.                  instance->host_no);
  7065.  #endif
  7066.              }
  7067.              } /* if target/lun is not busy */
  7068. +        }
  7069.          } /* if (!hostdata->connected) */
  7070.          
  7071.          if (hostdata->connected 
  7072. @@ -1373,6 +1380,11 @@
  7073.       * data bus during SELECTION.
  7074.       */
  7075.  
  7076. +    cli();
  7077. +    if (hostdata->connected) {
  7078. +    sti();
  7079. +    return -1;
  7080. +    }
  7081.      NCR5380_write(TARGET_COMMAND_REG, 0);
  7082.  
  7083.      /* Start arbitration */ 
  7084. @@ -1382,6 +1394,7 @@
  7085.      /* Wait for arbitration logic to complete */
  7086.      while (!(NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_PROGRESS));
  7087.  
  7088. +    sti();
  7089.  #if (NDEBUG & NDEBUG_ARBITRATION) 
  7090.      printk("scsi%d : arbitration complete\n", instance->host_no);
  7091.  /* Avoid GCC 2.4.5 asm needs to many reloads error */
  7092. @@ -1400,7 +1413,8 @@
  7093.      /* Check for lost arbitration */
  7094.      if ((NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) ||
  7095.      (NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_higher_mask) ||
  7096. -    (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) {
  7097. +    (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) ||
  7098. +    hostdata->connected) {
  7099.      NCR5380_write(MODE_REG, MR_BASE); 
  7100.  #if (NDEBUG & NDEBUG_ARBITRATION)
  7101.      printk("scsi%d : lost arbitration, deasserting MR_ARBITRATE\n", 
  7102. @@ -1428,6 +1442,12 @@
  7103.  
  7104.      udelay(2);    
  7105.  
  7106. +    if (hostdata->connected) {
  7107. +    NCR5380_write(MODE_REG, MR_BASE);
  7108. +    NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
  7109. +    return -1;
  7110. +    }
  7111. +
  7112.  #if (NDEBUG & NDEBUG_ARBITRATION)
  7113.      printk("scsi%d : won arbitration\n", instance->host_no);
  7114.  #endif
  7115. @@ -1453,6 +1473,12 @@
  7116.       * Reselect interrupts must be turned off prior to the dropping of BSY,
  7117.       * otherwise we will trigger an interrupt.
  7118.       */
  7119. +
  7120. +    if (hostdata->connected) {
  7121. +    NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
  7122. +    return -1;
  7123. +    }
  7124. +
  7125.      NCR5380_write(SELECT_ENABLE_REG, 0);
  7126.  
  7127.      /* Reset BSY */
  7128. @@ -1764,9 +1790,6 @@
  7129.      instance->host_no, instance->dma_channel, (p & SR_IO) ? "reading" :
  7130.      "writing", c, (p & SR_IO) ? "to" : "from", (unsigned) d);
  7131.  #endif
  7132. -    hostdata->dma_len = (p & SR_IO) ?
  7133. -    NCR5380_dma_read_setup(instance, d, c) : 
  7134. -    NCR5380_dma_write_setup(instance, d, c);
  7135.  #endif
  7136.  
  7137.      NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p));
  7138. @@ -1798,6 +1821,13 @@
  7139.      NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA);
  7140.      NCR5380_write(START_DMA_SEND_REG, 0);
  7141.      }
  7142. +#if defined(REAL_DMA) || defined(REAL_DMA_POLL) 
  7143. +    cli();
  7144. +    hostdata->dma_len = (p & SR_IO) ?
  7145. +    NCR5380_dma_read_setup(instance, d, c) : 
  7146. +    NCR5380_dma_write_setup(instance, d, c);
  7147. +    sti();
  7148. +#endif
  7149.  
  7150.  #if defined(REAL_DMA_POLL)
  7151.      do {
  7152. @@ -2084,19 +2114,13 @@
  7153.  /* ++roman: I suggest, this should be
  7154.   *   #if def(REAL_DMA) || def(PSEUDO_DMA) || ...
  7155.   * instead of leaving REAL_DMA out.
  7156. - *
  7157. - * GK: this does not work on FALCON:
  7158. - *   #if def(REAL_DMA) || def(PSEUDO_DMA) || ... 
  7159. - *       ^^^^^^^^^^^^^^^^
  7160. - *   results in timeout during partition check --> timeout in abort -->
  7161. - *   timeout in reset --> kernel panic
  7162.   */
  7163.  
  7164.          CHECK_ICNT("starting transf in inform_transf");
  7165. -#if /*defined(REAL_DMA) ||*/ defined(PSEUDO_DMA) || defined(REAL_DMA_POLL)
  7166. +#if defined(REAL_DMA) || defined(PSEUDO_DMA) || defined(REAL_DMA_POLL)
  7167.  #ifdef NCR5380_dma_xfer_len
  7168.          if (!scsi_devices[cmd->index].borken &&
  7169. -            (transfersize = NCR5380_dma_xfer_len(instance, cmd)) > 7) {
  7170. +            (transfersize = NCR5380_dma_xfer_len(instance, cmd)) > 31) {
  7171.  #else
  7172.          if (!scsi_devices[cmd->index].borken && 
  7173.              (transfersize = cmd->transfersize) && 
  7174. @@ -2144,6 +2168,7 @@
  7175.           */
  7176.          len = 1;
  7177.          data = &tmp;
  7178. +        NCR5380_write(SELECT_ENABLE_REG, 0);     /* disable reselects */
  7179.          NCR5380_transfer_pio(instance, &phase, &len, &data);
  7180.          cmd->SCp.Message = tmp;
  7181.  
  7182. @@ -2165,6 +2190,8 @@
  7183.              printk("scsi%d : target %d lun %d linked command complete.\n",
  7184.              instance->host_no, cmd->target, cmd->lun);
  7185.  #endif
  7186. +            /* Enable reselect interupts */
  7187. +            NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
  7188.              /* 
  7189.               * Sanity check : A linked command should only terminate with
  7190.               * one of these messages if there are more linked commands
  7191. @@ -2200,6 +2227,8 @@
  7192.              instance->host_no, cmd->target, cmd->lun);
  7193.  #endif
  7194.              hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
  7195. +            /* Enable reselect interupts */
  7196. +            NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
  7197.  
  7198.              /* ++roman: For Falcon SCSI, release the lock an on the
  7199.               * ST-DMA here if no other commands are waiting on the
  7200. @@ -2282,6 +2311,8 @@
  7201.              !hostdata->connected);
  7202.              return;
  7203.          case MESSAGE_REJECT:
  7204. +            /* Enable reselect interupts */
  7205. +            NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
  7206.              switch (hostdata->last_message) {
  7207.              case HEAD_OF_QUEUE_TAG:
  7208.              case ORDERED_QUEUE_TAG:
  7209. @@ -2293,8 +2324,8 @@
  7210.              break;
  7211.              }
  7212.          case DISCONNECT:
  7213. -            scsi_devices[cmd->index].disconnect = 1;
  7214.              cli();
  7215. +            scsi_devices[cmd->index].disconnect = 1;
  7216.              cmd->host_scribble = (unsigned char *) 
  7217.              hostdata->disconnected_queue;
  7218.              hostdata->connected = NULL;
  7219. @@ -2324,8 +2355,12 @@
  7220.           */
  7221.          case SAVE_POINTERS:
  7222.          case RESTORE_POINTERS:
  7223. +            /* Enable reselect interupts */
  7224. +            NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
  7225.              break;
  7226.          default:
  7227. +            /* Enable reselect interupts */
  7228. +            NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
  7229.  /* 
  7230.   * XXX rejected messages should be handled in the pio data transfer phase,
  7231.   * since ATN should be raised before ACK goes false when we reject a message
  7232. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/drivers/scsi/atari_sc.c linux-0.9pl4/drivers/scsi/atari_sc.c
  7233. --- linux-0.9pl3/drivers/scsi/atari_sc.c    Sun Aug 14 10:30:50 1994
  7234. +++ linux-0.9pl4/drivers/scsi/atari_sc.c    Wed Dec 31 19:00:00 1969
  7235. @@ -1,763 +0,0 @@
  7236. -/*
  7237. - * atari_scsi.c -- Device dependant functions for the Atari generic SCSI port
  7238. - *
  7239. - * Copyright 1994 Roman Hodek
  7240. - *   EMail: rnhodek@cip.informatik.uni-erlangen.de (Internet)
  7241. - *      or: Roman_Hodek@n.maus.de (MausNet, NO mail > 16 KB!)
  7242. - *
  7243. - *   Loosely based on the work of Robert De Vries' team and added:
  7244. - *    - working real DMA
  7245. - *    - Falcon support (untested yet!)   ++bjoern fixed and now it works
  7246. - *    - lots of extensions and bug fixes.
  7247. - *
  7248. - * This file is subject to the terms and conditions of the GNU General Public
  7249. - * License.  See the file README.legal in the main directory of this archive
  7250. - * for more details.
  7251. - *
  7252. - */
  7253. -
  7254. -
  7255. -/**************************************************************************/
  7256. -/*                                                                        */
  7257. -/* Notes for Falcon SCSI:                                                 */
  7258. -/* ----------------------                                                 */
  7259. -/*                                                                        */
  7260. -/* Since the Falcon SCSI uses the ST-DMA chip, that is shared among       */
  7261. -/* several device drivers, locking and unlocking the access to this       */
  7262. -/* chip is required. But locking is not possible from an interrupt,       */
  7263. -/* since it puts the process to sleep if the lock is not available.       */
  7264. -/* This prevents "late" locking of the DMA chip, i.e. locking it just     */
  7265. -/* before using it, since in case of disconnection-reconnection           */
  7266. -/* commands, the DMA is started from the reselection interrupt.           */
  7267. -/*                                                                        */
  7268. -/* Two possible schemes for ST-DMA-locking would be:                      */
  7269. -/*  1) The lock is taken for each command separately and disconnecting    */
  7270. -/*     is forbidden (i.e. can_queue = 1).                                 */
  7271. -/*  2) The DMA chip is locked when the first command comes in and         */
  7272. -/*     released when the last command is finished and all queues are      */
  7273. -/*     empty.                                                             */
  7274. -/* The first alternative would result in bad performance, since the       */
  7275. -/* interleaving of commands would not be used. The second is unfair to    */
  7276. -/* other drivers using the ST-DMA, because the queues will seldom be      */
  7277. -/* totally empty if there is a lot of disk traffic.                       */
  7278. -/*                                                                        */
  7279. -/* For this reasons I decided to employ a more elaborate scheme:          */
  7280. -/*  - First, we give up the lock everytime we can (for fairness), this    */
  7281. -/*    means every time a command finishes and there are no other commands */
  7282. -/*    on the disconnected queue.                                          */
  7283. -/*  - If there are others waiting to lock the DMA chip, we stop           */
  7284. -/*    issueing commands, i.e. moving them onto the issue queue.           */
  7285. -/*    Because of that, the disconnected queue will run empty in a         */
  7286. -/*    while. Instead we go to sleep on a 'fairness_queue'.                */
  7287. -/*  - If the lock is released, all processes waiting on the fairness      */
  7288. -/*    queue will be woken. The first of them trys to re-lock the DMA,     */
  7289. -/*    the others wait for the first to finish this task. After that,      */
  7290. -/*    they can all run on and do their commands...                        */
  7291. -/* This sounds complicated (and it is it :-(), but it seems to be a       */
  7292. -/* good compromise between fairness and performance: As long as noone     */
  7293. -/* else wants to work with the ST-DMA chip, SCSI can go along as          */
  7294. -/* usual. If now someone else comes, this behaviour is changed to a       */
  7295. -/* "fairness mode": just already initiated commands are finished and      */
  7296. -/* then the lock is released. The other one waiting will probably win     */
  7297. -/* the race for locking the DMA, since it was waiting for longer. And     */
  7298. -/* after it has finished, SCSI can go ahead again. Finally: I hope I      */
  7299. -/* have not produced any deadlock possibilites!                           */
  7300. -/*                                                                        */
  7301. -/**************************************************************************/
  7302. -
  7303. -
  7304. -
  7305. -#include <linux/config.h>
  7306. -
  7307. -#ifdef CONFIG_ATARI_SCSI
  7308. -
  7309. -/* #define NDEBUG (NDEBUG_DMA) */
  7310. -
  7311. -#define AUTOSENSE
  7312. -/* For the Atari version, use only polled IO or REAL_DMA */
  7313. -#define    REAL_DMA
  7314. -
  7315. -#if I_HAVE_OVERRUNS == 1 || I_HAVE_OVERRUNS == 2
  7316. -#define    READ_OVERRUNS
  7317. -#endif
  7318. -
  7319. -#include <linux/types.h>
  7320. -#include <linux/stddef.h>
  7321. -#include <linux/interrupt.h>
  7322. -#include <linux/bootinfo.h>
  7323. -#include <linux/atarihw.h>
  7324. -#include <linux/atariints.h>
  7325. -#include "../block/blk.h"
  7326. -#include "scsi.h"
  7327. -#include "hosts.h"
  7328. -#include "atari_scsi.h"
  7329. -#include "NCR5380.h"
  7330. -#include "constants.h"
  7331. -#include <linux/atari_stdma.h>
  7332. -
  7333. -
  7334. -#define    IS_A_TT()    (boot_info.bi_atari.model == ATARI_TT)
  7335. -
  7336. -#define    SCSI_DMA_WRITE_P(elt,val)                                    \
  7337. -    __asm__ __volatile__ ( "movepl %0,%1@(0)" : : "d" (val),        \
  7338. -                               "a" (&tt_scsi_dma.elt) );
  7339. -
  7340. -#define    SCSI_DMA_READ_P(elt) ({                                            \
  7341. -    unsigned long __val;                                                \
  7342. -    __asm__ __volatile__ ( "movepl %1@(0),%0"                            \
  7343. -                           : "=d" (__val) : "a" (&tt_scsi_dma.elt));    \
  7344. -    __val; })
  7345. -
  7346. -#define    SCSI_DMA_SETADR(adr)                    \
  7347. -    do {                                        \
  7348. -        unsigned long __adr = (adr);            \
  7349. -        st_dma.dma_lo = (unsigned char)__adr;    \
  7350. -        __adr >>= 8;                            \
  7351. -        st_dma.dma_md = (unsigned char)__adr;    \
  7352. -        __adr >>= 8;                            \
  7353. -        st_dma.dma_hi = (unsigned char)__adr;    \
  7354. -    } while(0)
  7355. -
  7356. -#define    SCSI_DMA_GETADR() ({                    \
  7357. -    unsigned long    __adr;                        \
  7358. -    __adr = st_dma.dma_lo;                        \
  7359. -    __asm__ __volatile__ ("nop");                \
  7360. -    __adr |= (st_dma.dma_md & 0xff) << 8;        \
  7361. -    __adr |= (st_dma.dma_hi & 0xff) << 16;        \
  7362. -    __adr;                                        \
  7363. -})
  7364. -
  7365. -
  7366. -
  7367. -/***************************** Prototypes *****************************/
  7368. -
  7369. -static void scsi_dma_buserr( struct intframe *fp, void *data);
  7370. -static void scsi_tt_intr( struct intframe *fp, void *data);
  7371. -static void scsi_falcon_intr( struct intframe *fp, void *data);
  7372. -static void atari_scsi_fetch_restbytes( void );
  7373. -static void falcon_release_lock_if_possible( struct NCR5380_hostdata *
  7374. -                                             hostdata );
  7375. -static void falcon_get_lock( void );
  7376. -static long atari_scsi_dma_residual( struct Scsi_Host *instance );
  7377. -static unsigned long atari_dma_xfer_len( unsigned long wanted_len );
  7378. -static unsigned char atari_scsi_tt_reg_read( unsigned char reg );
  7379. -static void atari_scsi_tt_reg_write( unsigned char reg, unsigned char value
  7380. -                                     );
  7381. -static unsigned char atari_scsi_falcon_reg_read( unsigned char reg );
  7382. -static void atari_scsi_falcon_reg_write( unsigned char reg, unsigned char
  7383. -                                         value );
  7384. -
  7385. -/************************* End of Prototypes **************************/
  7386. -
  7387. -
  7388. -static struct Scsi_Host *atari_scsi_host = NULL;
  7389. -static unsigned char (*atari_scsi_reg_read)( unsigned char reg );
  7390. -static void (*atari_scsi_reg_write)( unsigned char reg, unsigned char value );
  7391. -
  7392. -#ifdef REAL_DMA
  7393. -static unsigned long    atari_dma_residual, atari_dma_startaddr;
  7394. -static short            atari_dma_active;
  7395. -#endif
  7396. -
  7397. -
  7398. -#if defined(REAL_DMA)
  7399. -
  7400. -static int scsi_dma_is_ignored_buserr( unsigned char dma_stat )
  7401. -
  7402. -{    int                i;
  7403. -    unsigned long    addr = SCSI_DMA_READ_P( dma_addr_hi ), end_addr;
  7404. -
  7405. -    if (dma_stat & 0x01) {
  7406. -
  7407. -        /* A bus error happens when DMA-ing from the last page of a
  7408. -         * physical memory chunk (DMA prefetch!), but that doesn't hurt.
  7409. -         * Check for this case:
  7410. -         */
  7411. -        
  7412. -        for( i = 0; i < boot_info.num_memory; ++i ) {
  7413. -            end_addr = boot_info.memory[i].addr +
  7414. -                boot_info.memory[i].size;
  7415. -            if (end_addr <= addr && addr <= end_addr + 4)
  7416. -                return( 1 );
  7417. -        }
  7418. -    }
  7419. -    return( 0 );
  7420. -}
  7421. -
  7422. -
  7423. -static void scsi_dma_buserr (struct intframe *fp, void *data)
  7424. -
  7425. -{    unsigned char    dma_stat = tt_scsi_dma.dma_ctrl;
  7426. -
  7427. -    printk( "Bad SCSI DMA inmterrupt! dma_addr=0x%08lx dma_stat=%02x dma_cnt=%08lx\n",
  7428. -            SCSI_DMA_READ_P( dma_addr_hi ), dma_stat, SCSI_DMA_READ_P( dma_cnt_hi ) );
  7429. -    if (dma_stat & 0x80) {
  7430. -        if (!scsi_dma_is_ignored_buserr( dma_stat ))
  7431. -            panic( "SCSI DMA bus error -- bad DMA programming!" );
  7432. -    }
  7433. -    else {
  7434. -        /* Under normal circumstances we never should get to this point,
  7435. -         * since both interrupts are triggered simultaneosly and the 5380
  7436. -         * int has more priotity. When this irq is handled, that DMA
  7437. -         * interrupt is cleared. So a warning message is printed here.
  7438. -         */
  7439. -        printk( "SCSI DMA intr ?? -- this shouldn't happen!\n" );
  7440. -    }
  7441. -}
  7442. -
  7443. -#endif
  7444. -
  7445. -#undef    LOST_INTR
  7446. -
  7447. -#ifdef LOST_INTR
  7448. -extern volatile unsigned long intr_count;
  7449. -unsigned long curr_intr_count;
  7450. -
  7451. -#define    CHECK_ICNT(pos) do {                    \
  7452. - if (intr_count != curr_intr_count) {            \
  7453. -     printk( "INTR_COUNT changed before " pos    \
  7454. -             ": curr_cnt=%lu intr_cnt=%lu\n",    \
  7455. -             curr_intr_count, intr_count );        \
  7456. - }                                                \
  7457. -} while( 0 )
  7458. -
  7459. -#else
  7460. -
  7461. -#define    CHECK_ICNT(pos)
  7462. -
  7463. -#endif
  7464. -
  7465. -
  7466. -static void scsi_tt_intr (struct intframe *fp, void *data)
  7467. -
  7468. -{    int                dma_stat;
  7469. -    unsigned long    flags;
  7470. -#ifdef LOST_INTR
  7471. -    unsigned long    prev_intr_count;
  7472. -
  7473. -    prev_intr_count = curr_intr_count;
  7474. -    curr_intr_count = intr_count;
  7475. -#endif
  7476. -    
  7477. -#ifdef REAL_DMA
  7478. -
  7479. -    dma_stat = tt_scsi_dma.dma_ctrl;
  7480. -
  7481. -#if (NDEBUG & NDEBUG_INTR)
  7482. -    printk( "scsi%d: NCR5380 interupt, DMA status = %02x\n",
  7483. -            atari_scsi_host->host_no, dma_stat & 0xff );
  7484. -#endif
  7485. -
  7486. -    /* Look if it was the DMA that has interrupted: First possibility
  7487. -     * is that a bus error occured...
  7488. -     */
  7489. -    if (dma_stat & 0x80) {
  7490. -        if (!scsi_dma_is_ignored_buserr( dma_stat )) {
  7491. -            printk( "SCSI DMA caused bus error near 0x%08lx\n",
  7492. -                    SCSI_DMA_READ_P( dma_addr_hi ));
  7493. -            panic( "SCSI DMA bus error -- bad DMA programming!" );
  7494. -        }
  7495. -    }
  7496. -
  7497. -    /* If the DMA is active but not finished, we have the the case
  7498. -     * that some other 5380 interrupt occured within the DMA transfer.
  7499. -     * This means we have residual bytes, if the desired end address
  7500. -     * is not yet reached. Maybe we have to fetch some bytes from the
  7501. -     * rest data register, too. The residual must be calculated from
  7502. -     * the address pointer, not the counter register, because only the
  7503. -     * addr reg counts bytes not yet written and pending in the rest
  7504. -     * data reg!
  7505. -     */
  7506. -    if ((dma_stat & 0x02) && !(dma_stat & 0x40)) {
  7507. -        atari_dma_residual =
  7508. -            ((struct NCR5380_hostdata *)(atari_scsi_host->hostdata))->dma_len -
  7509. -                (SCSI_DMA_READ_P( dma_addr_hi ) - atari_dma_startaddr);
  7510. -#if (NDEBUG & NDEBUG_DMA)
  7511. -        printk( "SCSI DMA: There are %ld residual bytes.\n",
  7512. -                atari_dma_residual );
  7513. -#endif
  7514. -        atari_scsi_fetch_restbytes();
  7515. -        tt_scsi_dma.dma_ctrl = 0;
  7516. -    }
  7517. -
  7518. -    /* If the DMA is finished, fetch the rest bytes and turn it off */
  7519. -    if (dma_stat & 0x40) {
  7520. -        atari_dma_residual = 0;
  7521. -        atari_scsi_fetch_restbytes();
  7522. -        tt_scsi_dma.dma_ctrl = 0;
  7523. -    }
  7524. -
  7525. -#endif /* REAL_DMA */
  7526. -    
  7527. -    /* If we got this interrupt, we don't need the other one any more */
  7528. -    tt_mfp.int_pn_b = (unsigned char)~0x80;
  7529. -
  7530. -    CHECK_ICNT("calling NCR5380_intr");
  7531. -
  7532. -    save_flags(flags);
  7533. -    NCR5380_intr( 0 );
  7534. -    restore_flags(flags);
  7535. -
  7536. -#ifdef LOST_INTR
  7537. -    CHECK_ICNT("returning, after NCR5380_intr");
  7538. -    curr_intr_count = prev_intr_count;
  7539. -#endif
  7540. -}
  7541. -
  7542. -
  7543. -static void scsi_falcon_intr (struct intframe *fp, void *data)
  7544. -
  7545. -{    int                dma_stat;
  7546. -    unsigned long    flags;
  7547. -#ifdef LOST_INTR
  7548. -    unsigned long    prev_intr_count;
  7549. -
  7550. -    prev_intr_count = curr_intr_count;
  7551. -    curr_intr_count = intr_count;
  7552. -#endif
  7553. -    
  7554. -#ifdef REAL_DMA
  7555. -
  7556. -    /* Turn off DMA and select sector counter register before
  7557. -     * accessing the status register (Atari recommendation!)
  7558. -     */
  7559. -    st_dma.dma_mode_status = 0x90;
  7560. -    dma_stat = st_dma.dma_mode_status;
  7561. -
  7562. -    /* Bit 0 indicates some error in the DMA process... don't know
  7563. -     * what happened exactly (no further docu).
  7564. -     */
  7565. -    if (!(dma_stat & 0x01)) {
  7566. -        /* DMA error */
  7567. -        printk( "SCSI DMA error near 0x%08lx!\n", SCSI_DMA_GETADR() );
  7568. -    }
  7569. -
  7570. -    /* If the DMA was active, but now bit 1 is not clear, it is some
  7571. -     * other 5380 interrupt that finishes the DMA transfer. We have to
  7572. -     * calculate the number of residual bytes and give a warning if
  7573. -     * bytes are stuck in the ST-DMA fifo (there's no way to reach them!)
  7574. -     */
  7575. -    if (atari_dma_active && (dma_stat & 0x02)) {
  7576. -        unsigned long    transferred;
  7577. -
  7578. -        transferred = SCSI_DMA_GETADR() - atari_dma_startaddr;
  7579. -        /* The ST-DMA address is incremented in 2-byte steps, but the
  7580. -         * data are written only in 16-byte chunks. If the number of
  7581. -         * transferred bytes is not divisible by 16, the remainder is
  7582. -         * lost somewhere in outer space.
  7583. -         */
  7584. -        if (transferred & 15)
  7585. -            printk( "SCSI DMA error: %ld bytes lost in ST-DMA fifo :-((\n",
  7586. -                    transferred & 15 );
  7587. -
  7588. -        atari_dma_residual =
  7589. -            ((struct NCR5380_hostdata *)(atari_scsi_host->hostdata))->dma_len -
  7590. -                transferred;
  7591. -#if (NDEBUG & NDEBUG_DMA)
  7592. -        printk( "SCSI DMA: There are %ld residual bytes.\n",
  7593. -                atari_dma_residual );
  7594. -#endif
  7595. -    }
  7596. -    else
  7597. -        atari_dma_residual = 0;
  7598. -    atari_dma_active = 0;
  7599. -    
  7600. -#endif /* REAL_DMA */
  7601. -
  7602. -    CHECK_ICNT("calling NCR5380_intr");
  7603. -
  7604. -    save_flags(flags);
  7605. -    NCR5380_intr( 0 );
  7606. -    restore_flags(flags);
  7607. -
  7608. -#ifdef LOST_INTR
  7609. -    CHECK_ICNT("returning, after NCR5380_intr");
  7610. -    curr_intr_count = prev_intr_count;
  7611. -#endif
  7612. -}
  7613. -
  7614. -
  7615. -static void atari_scsi_fetch_restbytes( void )
  7616. -
  7617. -{    int        nr;
  7618. -    char    *src, *dst;
  7619. -
  7620. -    /* fetch rest bytes in the DMA register */
  7621. -    dst = (char *)SCSI_DMA_READ_P( dma_addr_hi );
  7622. -    if ((nr = ((long)dst & 3))) {
  7623. -        /* there are 'nr' bytes left for the last long address before the
  7624. -           DMA pointer */
  7625. -        dst = (char *)( (unsigned long)dst & ~3 );
  7626. -#if (NDEBUG & NDEBUG_DMA)
  7627. -        printk( "SCSI DMA: there are %d rest bytes for phys addr 0x%08lx",
  7628. -                nr, (long)dst );
  7629. -#endif
  7630. -        dst = (char *)PTOV(dst);  /* The content of the DMA pointer
  7631. -                                   * is a physical address! */
  7632. -#if (NDEBUG & NDEBUG_DMA)
  7633. -        printk( " = virt addr 0x%08lx\n", (long)dst );
  7634. -#endif
  7635. -        for( src = (char *)&tt_scsi_dma.dma_restdata; nr > 0; --nr )
  7636. -            *dst++ = *src++;
  7637. -    }
  7638. -}
  7639. -
  7640. -
  7641. -static int                    falcon_got_lock = 0;
  7642. -static struct wait_queue    *falcon_fairness_wait = NULL;
  7643. -static int                    falcon_trying_lock = 0;
  7644. -static struct wait_queue    *falcon_try_wait = NULL;
  7645. -
  7646. -/* This function releases the lock on the DMA chip if there is no
  7647. - * connected command and the disconnected queue is empty. On
  7648. - * releasing, instances of falcon_get_lock are awoken, that put
  7649. - * themselves to sleep for fairness. They can now try to get the lock
  7650. - * again (but others waiting longer more probably will win).
  7651. - */
  7652. -
  7653. -static void
  7654. -falcon_release_lock_if_possible( struct NCR5380_hostdata * hostdata )
  7655. -
  7656. -{
  7657. -    if (IS_A_TT()) return;
  7658. -    
  7659. -    if (falcon_got_lock &&
  7660. -        !hostdata->disconnected_queue &&
  7661. -        !hostdata->issue_queue &&
  7662. -        !hostdata->connected) {
  7663. -
  7664. -        unsigned long    oldflags;
  7665. -
  7666. -        save_flags(oldflags);
  7667. -        cli();
  7668. -        
  7669. -        falcon_got_lock = 0;
  7670. -        stdma_release();
  7671. -        wake_up( &falcon_fairness_wait );
  7672. -
  7673. -        restore_flags(oldflags);
  7674. -    }
  7675. -}
  7676. -
  7677. -/* This function manages the locking of the ST-DMA.
  7678. - * If the DMA isn't locked already for SCSI, it trys to lock it by
  7679. - * calling stdma_lock(). But if the DMA is locked by the SCSI code and
  7680. - * there are other drivers waiting for the chip, we do not issue the
  7681. - * command immediatly but wait on 'falcon_fairness_queue'. We will be
  7682. - * waked up when the DMA is unlocked by some SCSI interrupt. After that
  7683. - * we try to get the lock again.
  7684. - * But we must be prepared that more then one instance of
  7685. - * falcon_get_lock() is waiting on the fairness queue. They should not
  7686. - * try all at once to call stdma_lock(), one is enough! For that, the
  7687. - * first one sets 'falcon_trying_lock', others that see that variable
  7688. - * set wait on the queue 'falcon_try_wait'.
  7689. - * Complicated, complicated.... Sigh...
  7690. - */
  7691. -
  7692. -static void falcon_get_lock( void )
  7693. -
  7694. -{
  7695. -    unsigned long    oldflags;
  7696. -    
  7697. -    if (IS_A_TT()) return;
  7698. -
  7699. -    save_flags(oldflags);
  7700. -    cli();
  7701. -    
  7702. -    while( falcon_got_lock && stdma_others_waiting() )
  7703. -        sleep_on( &falcon_fairness_wait );
  7704. -
  7705. -    if (!falcon_got_lock) {
  7706. -        if (!falcon_trying_lock) {
  7707. -            falcon_trying_lock = 1;
  7708. -            stdma_lock( scsi_falcon_intr, 0 );
  7709. -            falcon_got_lock = 1;
  7710. -            falcon_trying_lock = 0;
  7711. -            wake_up( &falcon_try_wait );
  7712. -        }
  7713. -        else {
  7714. -            sleep_on( &falcon_try_wait );
  7715. -        }
  7716. -    }    
  7717. -
  7718. -    restore_flags(oldflags);
  7719. -}
  7720. -
  7721. -
  7722. -/* This is the wrapper function for NCR5380_queue_command(). It just
  7723. - * trys to get the lock on the ST-DMA (see above) and then calls the
  7724. - * original function.
  7725. - */
  7726. -
  7727. -int atari_queue_command (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
  7728. -
  7729. -{
  7730. -    falcon_get_lock();
  7731. -    return( NCR5380_queue_command( cmd, done ) );
  7732. -}
  7733. -
  7734. -
  7735. -                   
  7736. -int atari_scsi_detect (int hostno)
  7737. -
  7738. -{    static int called = 0;
  7739. -    struct Scsi_Host *instance;
  7740. -
  7741. -    if (boot_info.machtype != MACH_ATARI || called)
  7742. -        return( 0 );
  7743. -    
  7744. -    atari_scsi_reg_read  = IS_A_TT() ? atari_scsi_tt_reg_read :
  7745. -                                       atari_scsi_falcon_reg_read;
  7746. -    atari_scsi_reg_write = IS_A_TT() ? atari_scsi_tt_reg_write :
  7747. -                                       atari_scsi_falcon_reg_write;
  7748. -
  7749. -    instance = scsi_register (hostno, sizeof (struct NCR5380_hostdata));
  7750. -    atari_scsi_host = instance;
  7751. -
  7752. -    NCR5380_init (instance);
  7753. -    instance->irq = 0;    /* not needed, but tested in NCR5380.c */
  7754. -
  7755. -    if (IS_A_TT()) {
  7756. -        
  7757. -        add_isr( IRQ_TT_MFP_SCSI, scsi_tt_intr, 0, NULL);
  7758. -        tt_mfp.active_edge |= 0x80;        /* SCSI int on L->H */
  7759. -        tt_mfp.int_en_a |= 0x80;        /* enabled */
  7760. -        tt_mfp.int_mk_a |= 0x80;        /* not masked */
  7761. -#ifdef REAL_DMA
  7762. -        /* On the TT, we got a second interrupt for DMA ready and DMA buserror.
  7763. -         * Since on DMA ready we get a "normal" interrupt, too, the service
  7764. -         * routine for the second int just checks for buserrs.
  7765. -         */
  7766. -        add_isr( IRQ_TT_MFP_SCSIDMA, scsi_dma_buserr, 0, NULL);
  7767. -        tt_mfp.active_edge &= ~0x20;    /* DMA int on H->L */
  7768. -        tt_mfp.int_en_b |= 0x80;        /* enabled */
  7769. -        tt_mfp.int_mk_b |= 0x80;        /* not masked */
  7770. -
  7771. -        tt_scsi_dma.dma_ctrl = 0;
  7772. -        atari_dma_residual = 0;
  7773. -#endif /* REAL_DMA */
  7774. -
  7775. -    }
  7776. -    else { /* ! IS_A_TT */
  7777. -        
  7778. -        /* Nothing to do for the interrupt: the ST-DMA is initialized
  7779. -         * already by atari_init_INTS()
  7780. -         */
  7781. -
  7782. -#ifdef REAL_DMA
  7783. -        atari_dma_residual = 0;
  7784. -        atari_dma_active = 0;
  7785. -#endif
  7786. -
  7787. -        /* Falcon's ST-DMA can work only in lower 16 MB, so
  7788. -         * unchecked_isa_dma has to be set. But... the high level
  7789. -         * codes allocates lots (!) of memory for buffers if this is
  7790. -         * done. So the values for sg_tablesize and cmd_per_lun get
  7791. -         * lowered a bit (you can leave this out if you have 16MB of
  7792. -         * ST-Ram).
  7793. -         */
  7794. -        atari_scsi_host->unchecked_isa_dma =
  7795. -        atari_scsi_host->hostt->unchecked_isa_dma = 1;
  7796. -#if I_HAVE_OVERRUNS == 3
  7797. -        atari_scsi_host->sg_tablesize =
  7798. -        atari_scsi_host->hostt->sg_tablesize = SG_NONE;
  7799. -#else
  7800. -        atari_scsi_host->sg_tablesize =
  7801. -        atari_scsi_host->hostt->sg_tablesize = 8;
  7802. -#endif
  7803. -        atari_scsi_host->hostt->cmd_per_lun = 8;
  7804. -    }
  7805. -    
  7806. -    printk( "scsi%d: options CAN_QUEUE=%d CMD_PER_LUN=%d SCATTERGATHER=%d",
  7807. -            instance->host_no, instance->hostt->can_queue,
  7808. -            instance->hostt->cmd_per_lun,
  7809. -            instance->hostt->sg_tablesize );
  7810. -    NCR5380_print_options (instance);
  7811. -    printk ("\n");
  7812. -
  7813. -    called = 1;
  7814. -
  7815. -    return( 1 );
  7816. -}
  7817. -
  7818. -int atari_scsi_reset( Scsi_Cmnd *cmd )
  7819. -
  7820. -{    int        rv;
  7821. -    
  7822. -    /* For doing the reset, SCSI interrupts must be disabled first,
  7823. -     * since the 5380 raises its IRQ line while _RST is active and we
  7824. -     * can't disable interrupts completely, since we need the timer.
  7825. -     */
  7826. -    
  7827. -    if (IS_A_TT())
  7828. -        tt_mfp.int_en_a &= ~0x80;
  7829. -    else
  7830. -        mfp.int_en_b &= ~0x80;
  7831. -    
  7832. -    rv = NCR5380_reset( cmd );
  7833. -
  7834. -    /* Re-enable ints and abort a maybe active DMA transfer */
  7835. -    if (IS_A_TT()) {
  7836. -#ifdef REAL_DMA
  7837. -        tt_scsi_dma.dma_ctrl = 0;
  7838. -#endif /* REAL_DMA */
  7839. -        tt_mfp.int_en_a |= 0x80;
  7840. -    }
  7841. -    else {
  7842. -#ifdef REAL_DMA
  7843. -        st_dma.dma_mode_status = 0x90;
  7844. -        atari_dma_active = 0;
  7845. -#endif /* REAL_DMA */
  7846. -        mfp.int_en_b |= 0x80;
  7847. -    }
  7848. -
  7849. -    return( rv );
  7850. -}
  7851. -
  7852. -    
  7853. -const char * atari_scsi_info( void )
  7854. -
  7855. -{    /* atari_scsi_detect() is verbose enough... */
  7856. -    static const char string[] = "";
  7857. -    return string;
  7858. -}
  7859. -
  7860. -
  7861. -#if defined(REAL_DMA) || defined(REAL_DMA_POLL) || defined(PSEUDO_DMA)
  7862. -
  7863. -unsigned long atari_scsi_dma_setup( struct Scsi_Host *instance, void *data,
  7864. -                                    unsigned long count, int dir )
  7865. -{
  7866. -    unsigned long addr = VTOP( data ),
  7867. -                  cando = atari_dma_xfer_len( count );
  7868. -
  7869. -#if (NDEBUG & NDEBUG_DMA)
  7870. -    printk ("scsi%d: setting up dma, data = %p, phys = %lx, count = %ld, cando = %ld, dir = %d\n",
  7871. -            instance->host_no, data, addr, count, cando, dir);
  7872. -#endif
  7873. -
  7874. -    atari_dma_startaddr = addr;    /* Needed for calculating residual later. */
  7875. -  
  7876. -    if (dir)
  7877. -        /* write: push any dirty cache out before sending it to the
  7878. -         * peripheral. (Must be done before DMA setup, since at least the
  7879. -         * ST-DMA begins to fill internal buffers right after setup.
  7880. -         */
  7881. -        cache_push( addr, cando );
  7882. -    else
  7883. -        /* read: invalidate any cache, may be altered after DMA without CPU
  7884. -         * knowledge
  7885. -         */
  7886. -        cache_clear( addr, cando );
  7887. -
  7888. -    if (cando == 0)
  7889. -        printk( "SCSI warning: DMA programed for 0 bytes !\n" );
  7890. -
  7891. -    if (IS_A_TT()) {
  7892. -    
  7893. -        tt_scsi_dma.dma_ctrl = dir;
  7894. -        SCSI_DMA_WRITE_P( dma_addr_hi, addr );
  7895. -        SCSI_DMA_WRITE_P( dma_cnt_hi, cando );
  7896. -        tt_scsi_dma.dma_ctrl = dir | 2;
  7897. -    }
  7898. -    else { /* ! IS_A_TT */
  7899. -  
  7900. -        /* set address */
  7901. -        SCSI_DMA_SETADR( addr );
  7902. -
  7903. -        /* toggle direction bit to clear FIFO and set DMA direction */
  7904. -        dir <<= 8;
  7905. -        st_dma.dma_mode_status = 0x90 | dir;
  7906. -        st_dma.dma_mode_status = 0x90 | (dir ^ 0x100);
  7907. -        st_dma.dma_mode_status = 0x90 | dir;
  7908. -        st_dma.fdc_acces_seccount = cando >> 9;
  7909. -
  7910. -        st_dma.dma_mode_status = 0x10 | dir;
  7911. -        /* need not restore value of dir, only boolean value is tested */
  7912. -        atari_dma_active = 1;
  7913. -    }
  7914. -    
  7915. -    return( cando );
  7916. -}
  7917. -
  7918. -
  7919. -static long atari_scsi_dma_residual( struct Scsi_Host *instance )
  7920. -
  7921. -{
  7922. -    return( atari_dma_residual );
  7923. -}
  7924. -
  7925. -/* This function calculates the number of bytes that can be transferred
  7926. - * via DMA. On the TT, this is arbitrary, but on the Falcon we have to use
  7927. - * the ST-DMA chip. There are only multiples of 512 bytes possible and
  7928. - * max. 256*512 bytes :-( This means also, that defining READ_OVERRUNS is
  7929. - * not possible, since that would require to program the DMA for n*512 - 2
  7930. - * bytes.
  7931. - */
  7932. -
  7933. -static unsigned long atari_dma_xfer_len( unsigned long wanted_len )
  7934. -
  7935. -{
  7936. -    unsigned long    possible_len;
  7937. -
  7938. -    if (IS_A_TT())
  7939. -        /* TT SCSI DMA can transfer arbitrary #bytes */
  7940. -        return( wanted_len );
  7941. -    
  7942. -    /* ST DMA chip is stupid -- only multiples of 512 bytes! (and max.
  7943. -     * 255*512 bytes, but this should be enough)
  7944. -     */
  7945. -    possible_len =wanted_len & ~0x1ff;
  7946. -    if (possible_len > 255*512)
  7947. -        possible_len = 255*512;
  7948. -
  7949. -#if (NDEBUG & NDEBUG_DMA)
  7950. -    if (possible_len != wanted_len)
  7951. -        printk( "Sorry, must cut DMA transfer size to %ld bytes instead of %ld\n",
  7952. -                possible_len, wanted_len );
  7953. -#endif
  7954. -
  7955. -    return( possible_len );
  7956. -}
  7957. -
  7958. -
  7959. -#endif    /* REAL_DMA || REAL_DMA_POLL || PSEUDO_DMA */
  7960. -
  7961. -
  7962. -/* NCR5380 register access functions
  7963. - *
  7964. - * There are seperate functions for TT and Falcon, because the access
  7965. - * methods are quite different. The calling macros NCR5380_read and
  7966. - * NCR5380_write call these functions via function pointers.
  7967. - */
  7968. -
  7969. -static unsigned char atari_scsi_tt_reg_read( unsigned char reg )
  7970. -
  7971. -{
  7972. -    return( tt_scsi_regp[reg * 2] );
  7973. -}
  7974. -
  7975. -static void atari_scsi_tt_reg_write( unsigned char reg, unsigned char value )
  7976. -
  7977. -{
  7978. -    tt_scsi_regp[reg * 2] = value;
  7979. -}
  7980. -
  7981. -static unsigned char atari_scsi_falcon_reg_read( unsigned char reg )
  7982. -
  7983. -{
  7984. -    dma_wd.dma_mode_status= (u_short)(0x88 + reg);
  7985. -    return( (u_char)dma_wd.fdc_acces_seccount );
  7986. -}
  7987. -
  7988. -static void atari_scsi_falcon_reg_write( unsigned char reg, unsigned char value )
  7989. -
  7990. -{
  7991. -    dma_wd.dma_mode_status = (u_short)(0x88 + reg);
  7992. -    dma_wd.fdc_acces_seccount = (u_short)value;
  7993. -}
  7994. -
  7995. -
  7996. -#include "atari_NCR5380.c"
  7997. -
  7998. -#endif /* CONFIG_ATARI_*_SCSI */
  7999. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/drivers/scsi/atari_scsi.c linux-0.9pl4/drivers/scsi/atari_scsi.c
  8000. --- linux-0.9pl3/drivers/scsi/atari_scsi.c    Wed Dec 31 19:00:00 1969
  8001. +++ linux-0.9pl4/drivers/scsi/atari_scsi.c    Mon Nov  7 22:28:17 1994
  8002. @@ -0,0 +1,766 @@
  8003. +/*
  8004. + * atari_scsi.c -- Device dependant functions for the Atari generic SCSI port
  8005. + *
  8006. + * Copyright 1994 Roman Hodek
  8007. + *   EMail: rnhodek@cip.informatik.uni-erlangen.de (Internet)
  8008. + *      or: Roman_Hodek@n.maus.de (MausNet, NO mail > 16 KB!)
  8009. + *
  8010. + *   Loosely based on the work of Robert De Vries' team and added:
  8011. + *    - working real DMA
  8012. + *    - Falcon support (untested yet!)   ++bjoern fixed and now it works
  8013. + *    - lots of extensions and bug fixes.
  8014. + *
  8015. + * This file is subject to the terms and conditions of the GNU General Public
  8016. + * License.  See the file README.legal in the main directory of this archive
  8017. + * for more details.
  8018. + *
  8019. + */
  8020. +
  8021. +
  8022. +/**************************************************************************/
  8023. +/*                                                                        */
  8024. +/* Notes for Falcon SCSI:                                                 */
  8025. +/* ----------------------                                                 */
  8026. +/*                                                                        */
  8027. +/* Since the Falcon SCSI uses the ST-DMA chip, that is shared among       */
  8028. +/* several device drivers, locking and unlocking the access to this       */
  8029. +/* chip is required. But locking is not possible from an interrupt,       */
  8030. +/* since it puts the process to sleep if the lock is not available.       */
  8031. +/* This prevents "late" locking of the DMA chip, i.e. locking it just     */
  8032. +/* before using it, since in case of disconnection-reconnection           */
  8033. +/* commands, the DMA is started from the reselection interrupt.           */
  8034. +/*                                                                        */
  8035. +/* Two possible schemes for ST-DMA-locking would be:                      */
  8036. +/*  1) The lock is taken for each command separately and disconnecting    */
  8037. +/*     is forbidden (i.e. can_queue = 1).                                 */
  8038. +/*  2) The DMA chip is locked when the first command comes in and         */
  8039. +/*     released when the last command is finished and all queues are      */
  8040. +/*     empty.                                                             */
  8041. +/* The first alternative would result in bad performance, since the       */
  8042. +/* interleaving of commands would not be used. The second is unfair to    */
  8043. +/* other drivers using the ST-DMA, because the queues will seldom be      */
  8044. +/* totally empty if there is a lot of disk traffic.                       */
  8045. +/*                                                                        */
  8046. +/* For this reasons I decided to employ a more elaborate scheme:          */
  8047. +/*  - First, we give up the lock everytime we can (for fairness), this    */
  8048. +/*    means every time a command finishes and there are no other commands */
  8049. +/*    on the disconnected queue.                                          */
  8050. +/*  - If there are others waiting to lock the DMA chip, we stop           */
  8051. +/*    issueing commands, i.e. moving them onto the issue queue.           */
  8052. +/*    Because of that, the disconnected queue will run empty in a         */
  8053. +/*    while. Instead we go to sleep on a 'fairness_queue'.                */
  8054. +/*  - If the lock is released, all processes waiting on the fairness      */
  8055. +/*    queue will be woken. The first of them trys to re-lock the DMA,     */
  8056. +/*    the others wait for the first to finish this task. After that,      */
  8057. +/*    they can all run on and do their commands...                        */
  8058. +/* This sounds complicated (and it is it :-(), but it seems to be a       */
  8059. +/* good compromise between fairness and performance: As long as noone     */
  8060. +/* else wants to work with the ST-DMA chip, SCSI can go along as          */
  8061. +/* usual. If now someone else comes, this behaviour is changed to a       */
  8062. +/* "fairness mode": just already initiated commands are finished and      */
  8063. +/* then the lock is released. The other one waiting will probably win     */
  8064. +/* the race for locking the DMA, since it was waiting for longer. And     */
  8065. +/* after it has finished, SCSI can go ahead again. Finally: I hope I      */
  8066. +/* have not produced any deadlock possibilites!                           */
  8067. +/*                                                                        */
  8068. +/**************************************************************************/
  8069. +
  8070. +
  8071. +
  8072. +#include <linux/config.h>
  8073. +
  8074. +#ifdef CONFIG_ATARI_SCSI
  8075. +
  8076. +/* #define NDEBUG (NDEBUG_DMA) */
  8077. +
  8078. +#define AUTOSENSE
  8079. +/* For the Atari version, use only polled IO or REAL_DMA */
  8080. +#define    REAL_DMA
  8081. +
  8082. +#if I_HAVE_OVERRUNS == 1 || I_HAVE_OVERRUNS == 2
  8083. +#define    READ_OVERRUNS
  8084. +#endif
  8085. +
  8086. +#include <linux/types.h>
  8087. +#include <linux/stddef.h>
  8088. +#include <linux/interrupt.h>
  8089. +#include <linux/bootinfo.h>
  8090. +#include <linux/delay.h>
  8091. +#include <linux/atarihw.h>
  8092. +#include <linux/atariints.h>
  8093. +#include "../block/blk.h"
  8094. +#include "scsi.h"
  8095. +#include "hosts.h"
  8096. +#include "atari_scsi.h"
  8097. +#include "NCR5380.h"
  8098. +#include "constants.h"
  8099. +#include <linux/atari_stdma.h>
  8100. +
  8101. +
  8102. +#define    IS_A_TT()    (boot_info.bi_atari.model == ATARI_TT)
  8103. +
  8104. +#define    SCSI_DMA_WRITE_P(elt,val)                                    \
  8105. +    __asm__ __volatile__ ( "movepl %0,%1@(0)" : : "d" (val),        \
  8106. +                               "a" (&tt_scsi_dma.elt) );
  8107. +
  8108. +#define    SCSI_DMA_READ_P(elt) ({                                            \
  8109. +    unsigned long __val;                                                \
  8110. +    __asm__ __volatile__ ( "movepl %1@(0),%0"                            \
  8111. +                           : "=d" (__val) : "a" (&tt_scsi_dma.elt));    \
  8112. +    __val; })
  8113. +
  8114. +#define    SCSI_DMA_SETADR(adr)                    \
  8115. +    do {                                        \
  8116. +        unsigned long __adr = (adr);            \
  8117. +        st_dma.dma_lo = (unsigned char)__adr;    \
  8118. +        __adr >>= 8;                            \
  8119. +        st_dma.dma_md = (unsigned char)__adr;    \
  8120. +        __adr >>= 8;                            \
  8121. +        st_dma.dma_hi = (unsigned char)__adr;    \
  8122. +    } while(0)
  8123. +
  8124. +#define    SCSI_DMA_GETADR() ({                    \
  8125. +    unsigned long    __adr;                        \
  8126. +    __adr = st_dma.dma_lo;                        \
  8127. +    __asm__ __volatile__ ("nop");                \
  8128. +    __adr |= (st_dma.dma_md & 0xff) << 8;        \
  8129. +    __adr |= (st_dma.dma_hi & 0xff) << 16;        \
  8130. +    __adr;                                        \
  8131. +})
  8132. +
  8133. +
  8134. +
  8135. +/***************************** Prototypes *****************************/
  8136. +
  8137. +static void scsi_dma_buserr( struct intframe *fp, void *data);
  8138. +static void scsi_tt_intr( struct intframe *fp, void *data);
  8139. +static void scsi_falcon_intr( struct intframe *fp, void *data);
  8140. +static void atari_scsi_fetch_restbytes( void );
  8141. +static void falcon_release_lock_if_possible( struct NCR5380_hostdata *
  8142. +                                             hostdata );
  8143. +static void falcon_get_lock( void );
  8144. +static long atari_scsi_dma_residual( struct Scsi_Host *instance );
  8145. +static unsigned long atari_dma_xfer_len( unsigned long wanted_len );
  8146. +static unsigned char atari_scsi_tt_reg_read( unsigned char reg );
  8147. +static void atari_scsi_tt_reg_write( unsigned char reg, unsigned char value
  8148. +                                     );
  8149. +static unsigned char atari_scsi_falcon_reg_read( unsigned char reg );
  8150. +static void atari_scsi_falcon_reg_write( unsigned char reg, unsigned char
  8151. +                                         value );
  8152. +
  8153. +/************************* End of Prototypes **************************/
  8154. +
  8155. +
  8156. +static struct Scsi_Host *atari_scsi_host = NULL;
  8157. +static unsigned char (*atari_scsi_reg_read)( unsigned char reg );
  8158. +static void (*atari_scsi_reg_write)( unsigned char reg, unsigned char value );
  8159. +
  8160. +#ifdef REAL_DMA
  8161. +static unsigned long    atari_dma_residual, atari_dma_startaddr;
  8162. +static short            atari_dma_active;
  8163. +#endif
  8164. +
  8165. +
  8166. +#if defined(REAL_DMA)
  8167. +
  8168. +static int scsi_dma_is_ignored_buserr( unsigned char dma_stat )
  8169. +
  8170. +{    int                i;
  8171. +    unsigned long    addr = SCSI_DMA_READ_P( dma_addr_hi ), end_addr;
  8172. +
  8173. +    if (dma_stat & 0x01) {
  8174. +
  8175. +        /* A bus error happens when DMA-ing from the last page of a
  8176. +         * physical memory chunk (DMA prefetch!), but that doesn't hurt.
  8177. +         * Check for this case:
  8178. +         */
  8179. +        
  8180. +        for( i = 0; i < boot_info.num_memory; ++i ) {
  8181. +            end_addr = boot_info.memory[i].addr +
  8182. +                boot_info.memory[i].size;
  8183. +            if (end_addr <= addr && addr <= end_addr + 4)
  8184. +                return( 1 );
  8185. +        }
  8186. +    }
  8187. +    return( 0 );
  8188. +}
  8189. +
  8190. +
  8191. +static void scsi_dma_buserr (struct intframe *fp, void *data)
  8192. +
  8193. +{    unsigned char    dma_stat = tt_scsi_dma.dma_ctrl;
  8194. +
  8195. +    printk( "Bad SCSI DMA inmterrupt! dma_addr=0x%08lx dma_stat=%02x dma_cnt=%08lx\n",
  8196. +            SCSI_DMA_READ_P( dma_addr_hi ), dma_stat, SCSI_DMA_READ_P( dma_cnt_hi ) );
  8197. +    if (dma_stat & 0x80) {
  8198. +        if (!scsi_dma_is_ignored_buserr( dma_stat ))
  8199. +            panic( "SCSI DMA bus error -- bad DMA programming!" );
  8200. +    }
  8201. +    else {
  8202. +        /* Under normal circumstances we never should get to this point,
  8203. +         * since both interrupts are triggered simultaneosly and the 5380
  8204. +         * int has more priotity. When this irq is handled, that DMA
  8205. +         * interrupt is cleared. So a warning message is printed here.
  8206. +         */
  8207. +        printk( "SCSI DMA intr ?? -- this shouldn't happen!\n" );
  8208. +    }
  8209. +}
  8210. +
  8211. +#endif
  8212. +
  8213. +#undef    LOST_INTR
  8214. +
  8215. +#ifdef LOST_INTR
  8216. +extern volatile unsigned long intr_count;
  8217. +unsigned long curr_intr_count;
  8218. +
  8219. +#define    CHECK_ICNT(pos) do {                    \
  8220. + if (intr_count != curr_intr_count) {            \
  8221. +     printk( "INTR_COUNT changed before " pos    \
  8222. +             ": curr_cnt=%lu intr_cnt=%lu\n",    \
  8223. +             curr_intr_count, intr_count );        \
  8224. + }                                                \
  8225. +} while( 0 )
  8226. +
  8227. +#else
  8228. +
  8229. +#define    CHECK_ICNT(pos)
  8230. +
  8231. +#endif
  8232. +
  8233. +
  8234. +static void scsi_tt_intr (struct intframe *fp, void *data)
  8235. +
  8236. +{    int                dma_stat;
  8237. +    unsigned long    flags;
  8238. +#ifdef LOST_INTR
  8239. +    unsigned long    prev_intr_count;
  8240. +
  8241. +    prev_intr_count = curr_intr_count;
  8242. +    curr_intr_count = intr_count;
  8243. +#endif
  8244. +    
  8245. +#ifdef REAL_DMA
  8246. +
  8247. +    dma_stat = tt_scsi_dma.dma_ctrl;
  8248. +
  8249. +#if (NDEBUG & NDEBUG_INTR)
  8250. +    printk( "scsi%d: NCR5380 interupt, DMA status = %02x\n",
  8251. +            atari_scsi_host->host_no, dma_stat & 0xff );
  8252. +#endif
  8253. +
  8254. +    /* Look if it was the DMA that has interrupted: First possibility
  8255. +     * is that a bus error occured...
  8256. +     */
  8257. +    if (dma_stat & 0x80) {
  8258. +        if (!scsi_dma_is_ignored_buserr( dma_stat )) {
  8259. +            printk( "SCSI DMA caused bus error near 0x%08lx\n",
  8260. +                    SCSI_DMA_READ_P( dma_addr_hi ));
  8261. +            panic( "SCSI DMA bus error -- bad DMA programming!" );
  8262. +        }
  8263. +    }
  8264. +
  8265. +    /* If the DMA is active but not finished, we have the the case
  8266. +     * that some other 5380 interrupt occured within the DMA transfer.
  8267. +     * This means we have residual bytes, if the desired end address
  8268. +     * is not yet reached. Maybe we have to fetch some bytes from the
  8269. +     * rest data register, too. The residual must be calculated from
  8270. +     * the address pointer, not the counter register, because only the
  8271. +     * addr reg counts bytes not yet written and pending in the rest
  8272. +     * data reg!
  8273. +     */
  8274. +    if ((dma_stat & 0x02) && !(dma_stat & 0x40)) {
  8275. +        atari_dma_residual =
  8276. +            ((struct NCR5380_hostdata *)(atari_scsi_host->hostdata))->dma_len -
  8277. +                (SCSI_DMA_READ_P( dma_addr_hi ) - atari_dma_startaddr);
  8278. +#if (NDEBUG & NDEBUG_DMA)
  8279. +        printk( "SCSI DMA: There are %ld residual bytes.\n",
  8280. +                atari_dma_residual );
  8281. +#endif
  8282. +        atari_scsi_fetch_restbytes();
  8283. +        tt_scsi_dma.dma_ctrl = 0;
  8284. +    }
  8285. +
  8286. +    /* If the DMA is finished, fetch the rest bytes and turn it off */
  8287. +    if (dma_stat & 0x40) {
  8288. +        atari_dma_residual = 0;
  8289. +        atari_scsi_fetch_restbytes();
  8290. +        tt_scsi_dma.dma_ctrl = 0;
  8291. +    }
  8292. +
  8293. +#endif /* REAL_DMA */
  8294. +    
  8295. +    /* If we got this interrupt, we don't need the other one any more */
  8296. +    tt_mfp.int_pn_b = (unsigned char)~0x80;
  8297. +
  8298. +    CHECK_ICNT("calling NCR5380_intr");
  8299. +
  8300. +    save_flags(flags);
  8301. +    NCR5380_intr( 0 );
  8302. +    restore_flags(flags);
  8303. +
  8304. +#ifdef LOST_INTR
  8305. +    CHECK_ICNT("returning, after NCR5380_intr");
  8306. +    curr_intr_count = prev_intr_count;
  8307. +#endif
  8308. +}
  8309. +
  8310. +
  8311. +static void scsi_falcon_intr (struct intframe *fp, void *data)
  8312. +
  8313. +{    int                dma_stat;
  8314. +    unsigned long    flags;
  8315. +#ifdef LOST_INTR
  8316. +    unsigned long    prev_intr_count;
  8317. +
  8318. +    prev_intr_count = curr_intr_count;
  8319. +    curr_intr_count = intr_count;
  8320. +#endif
  8321. +    
  8322. +#ifdef REAL_DMA
  8323. +
  8324. +    /* Turn off DMA and select sector counter register before
  8325. +     * accessing the status register (Atari recommendation!)
  8326. +     */
  8327. +    st_dma.dma_mode_status = 0x90;
  8328. +    dma_stat = st_dma.dma_mode_status;
  8329. +
  8330. +    /* Bit 0 indicates some error in the DMA process... don't know
  8331. +     * what happened exactly (no further docu).
  8332. +     */
  8333. +    if (!(dma_stat & 0x01)) {
  8334. +        /* DMA error */
  8335. +        printk( "SCSI DMA error near 0x%08lx!\n", SCSI_DMA_GETADR() );
  8336. +    }
  8337. +
  8338. +    /* If the DMA was active, but now bit 1 is not clear, it is some
  8339. +     * other 5380 interrupt that finishes the DMA transfer. We have to
  8340. +     * calculate the number of residual bytes and give a warning if
  8341. +     * bytes are stuck in the ST-DMA fifo (there's no way to reach them!)
  8342. +     */
  8343. +    if (atari_dma_active && (dma_stat & 0x02)) {
  8344. +        unsigned long    transferred;
  8345. +
  8346. +        transferred = SCSI_DMA_GETADR() - atari_dma_startaddr;
  8347. +        /* The ST-DMA address is incremented in 2-byte steps, but the
  8348. +         * data are written only in 16-byte chunks. If the number of
  8349. +         * transferred bytes is not divisible by 16, the remainder is
  8350. +         * lost somewhere in outer space.
  8351. +         */
  8352. +        if (transferred & 15)
  8353. +            printk( "SCSI DMA error: %ld bytes lost in ST-DMA fifo :-((\n",
  8354. +                    transferred & 15 );
  8355. +
  8356. +        atari_dma_residual =
  8357. +            ((struct NCR5380_hostdata *)(atari_scsi_host->hostdata))->dma_len -
  8358. +                transferred;
  8359. +#if (NDEBUG & NDEBUG_DMA)
  8360. +        printk( "SCSI DMA: There are %ld residual bytes.\n",
  8361. +                atari_dma_residual );
  8362. +#endif
  8363. +    }
  8364. +    else
  8365. +        atari_dma_residual = 0;
  8366. +    atari_dma_active = 0;
  8367. +    
  8368. +#endif /* REAL_DMA */
  8369. +
  8370. +    CHECK_ICNT("calling NCR5380_intr");
  8371. +
  8372. +    save_flags(flags);
  8373. +    NCR5380_intr( 0 );
  8374. +    restore_flags(flags);
  8375. +
  8376. +#ifdef LOST_INTR
  8377. +    CHECK_ICNT("returning, after NCR5380_intr");
  8378. +    curr_intr_count = prev_intr_count;
  8379. +#endif
  8380. +}
  8381. +
  8382. +
  8383. +static void atari_scsi_fetch_restbytes( void )
  8384. +
  8385. +{    int        nr;
  8386. +    char    *src, *dst;
  8387. +
  8388. +    /* fetch rest bytes in the DMA register */
  8389. +    dst = (char *)SCSI_DMA_READ_P( dma_addr_hi );
  8390. +    if ((nr = ((long)dst & 3))) {
  8391. +        /* there are 'nr' bytes left for the last long address before the
  8392. +           DMA pointer */
  8393. +        dst = (char *)( (unsigned long)dst & ~3 );
  8394. +#if (NDEBUG & NDEBUG_DMA)
  8395. +        printk( "SCSI DMA: there are %d rest bytes for phys addr 0x%08lx",
  8396. +                nr, (long)dst );
  8397. +#endif
  8398. +        dst = (char *)PTOV(dst);  /* The content of the DMA pointer
  8399. +                                   * is a physical address! */
  8400. +#if (NDEBUG & NDEBUG_DMA)
  8401. +        printk( " = virt addr 0x%08lx\n", (long)dst );
  8402. +#endif
  8403. +        for( src = (char *)&tt_scsi_dma.dma_restdata; nr > 0; --nr )
  8404. +            *dst++ = *src++;
  8405. +    }
  8406. +}
  8407. +
  8408. +
  8409. +static int                    falcon_got_lock = 0;
  8410. +static struct wait_queue    *falcon_fairness_wait = NULL;
  8411. +static int                    falcon_trying_lock = 0;
  8412. +static struct wait_queue    *falcon_try_wait = NULL;
  8413. +
  8414. +/* This function releases the lock on the DMA chip if there is no
  8415. + * connected command and the disconnected queue is empty. On
  8416. + * releasing, instances of falcon_get_lock are awoken, that put
  8417. + * themselves to sleep for fairness. They can now try to get the lock
  8418. + * again (but others waiting longer more probably will win).
  8419. + */
  8420. +
  8421. +static void
  8422. +falcon_release_lock_if_possible( struct NCR5380_hostdata * hostdata )
  8423. +
  8424. +{
  8425. +    if (IS_A_TT()) return;
  8426. +    
  8427. +    if (falcon_got_lock &&
  8428. +        !hostdata->disconnected_queue &&
  8429. +        !hostdata->issue_queue &&
  8430. +        !hostdata->connected) {
  8431. +
  8432. +        unsigned long    oldflags;
  8433. +
  8434. +        save_flags(oldflags);
  8435. +        cli();
  8436. +        
  8437. +        falcon_got_lock = 0;
  8438. +        stdma_release();
  8439. +        wake_up( &falcon_fairness_wait );
  8440. +
  8441. +        restore_flags(oldflags);
  8442. +    }
  8443. +}
  8444. +
  8445. +/* This function manages the locking of the ST-DMA.
  8446. + * If the DMA isn't locked already for SCSI, it trys to lock it by
  8447. + * calling stdma_lock(). But if the DMA is locked by the SCSI code and
  8448. + * there are other drivers waiting for the chip, we do not issue the
  8449. + * command immediatly but wait on 'falcon_fairness_queue'. We will be
  8450. + * waked up when the DMA is unlocked by some SCSI interrupt. After that
  8451. + * we try to get the lock again.
  8452. + * But we must be prepared that more then one instance of
  8453. + * falcon_get_lock() is waiting on the fairness queue. They should not
  8454. + * try all at once to call stdma_lock(), one is enough! For that, the
  8455. + * first one sets 'falcon_trying_lock', others that see that variable
  8456. + * set wait on the queue 'falcon_try_wait'.
  8457. + * Complicated, complicated.... Sigh...
  8458. + */
  8459. +
  8460. +static void falcon_get_lock( void )
  8461. +
  8462. +{
  8463. +    unsigned long    oldflags;
  8464. +    
  8465. +    if (IS_A_TT()) return;
  8466. +
  8467. +    save_flags(oldflags);
  8468. +    cli();
  8469. +    
  8470. +    while( falcon_got_lock && stdma_others_waiting() )
  8471. +        sleep_on( &falcon_fairness_wait );
  8472. +
  8473. +    if (!falcon_got_lock) {
  8474. +        if (!falcon_trying_lock) {
  8475. +            falcon_trying_lock = 1;
  8476. +            stdma_lock( scsi_falcon_intr, 0 );
  8477. +            falcon_got_lock = 1;
  8478. +            falcon_trying_lock = 0;
  8479. +            wake_up( &falcon_try_wait );
  8480. +        }
  8481. +        else {
  8482. +            sleep_on( &falcon_try_wait );
  8483. +        }
  8484. +    }    
  8485. +
  8486. +    restore_flags(oldflags);
  8487. +}
  8488. +
  8489. +
  8490. +/* This is the wrapper function for NCR5380_queue_command(). It just
  8491. + * trys to get the lock on the ST-DMA (see above) and then calls the
  8492. + * original function.
  8493. + */
  8494. +
  8495. +int atari_queue_command (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
  8496. +
  8497. +{
  8498. +    falcon_get_lock();
  8499. +    return( NCR5380_queue_command( cmd, done ) );
  8500. +}
  8501. +
  8502. +
  8503. +                   
  8504. +int atari_scsi_detect (int hostno)
  8505. +
  8506. +{    static int called = 0;
  8507. +    struct Scsi_Host *instance;
  8508. +
  8509. +    if (boot_info.machtype != MACH_ATARI || called)
  8510. +        return( 0 );
  8511. +    
  8512. +    atari_scsi_reg_read  = IS_A_TT() ? atari_scsi_tt_reg_read :
  8513. +                                       atari_scsi_falcon_reg_read;
  8514. +    atari_scsi_reg_write = IS_A_TT() ? atari_scsi_tt_reg_write :
  8515. +                                       atari_scsi_falcon_reg_write;
  8516. +
  8517. +    instance = scsi_register (hostno, sizeof (struct NCR5380_hostdata));
  8518. +    atari_scsi_host = instance;
  8519. +
  8520. +    NCR5380_init (instance);
  8521. +    instance->irq = 0;    /* not needed, but tested in NCR5380.c */
  8522. +
  8523. +    if (IS_A_TT()) {
  8524. +        
  8525. +        add_isr( IRQ_TT_MFP_SCSI, scsi_tt_intr, 0, NULL);
  8526. +        tt_mfp.active_edge |= 0x80;        /* SCSI int on L->H */
  8527. +        tt_mfp.int_en_a |= 0x80;        /* enabled */
  8528. +        tt_mfp.int_mk_a |= 0x80;        /* not masked */
  8529. +#ifdef REAL_DMA
  8530. +        /* On the TT, we got a second interrupt for DMA ready and DMA buserror.
  8531. +         * Since on DMA ready we get a "normal" interrupt, too, the service
  8532. +         * routine for the second int just checks for buserrs.
  8533. +         */
  8534. +        add_isr( IRQ_TT_MFP_SCSIDMA, scsi_dma_buserr, 0, NULL);
  8535. +        tt_mfp.active_edge &= ~0x20;    /* DMA int on H->L */
  8536. +        tt_mfp.int_en_b |= 0x80;        /* enabled */
  8537. +        tt_mfp.int_mk_b |= 0x80;        /* not masked */
  8538. +
  8539. +        tt_scsi_dma.dma_ctrl = 0;
  8540. +        atari_dma_residual = 0;
  8541. +#endif /* REAL_DMA */
  8542. +
  8543. +    }
  8544. +    else { /* ! IS_A_TT */
  8545. +        
  8546. +        /* Nothing to do for the interrupt: the ST-DMA is initialized
  8547. +         * already by atari_init_INTS()
  8548. +         */
  8549. +
  8550. +#ifdef REAL_DMA
  8551. +        atari_dma_residual = 0;
  8552. +        atari_dma_active = 0;
  8553. +#endif
  8554. +
  8555. +        /* Falcon's ST-DMA can work only in lower 16 MB, so
  8556. +         * unchecked_isa_dma has to be set. But... the high level
  8557. +         * codes allocates lots (!) of memory for buffers if this is
  8558. +         * done. So the values for sg_tablesize and cmd_per_lun get
  8559. +         * lowered a bit (you can leave this out if you have 16MB of
  8560. +         * ST-Ram).
  8561. +         */
  8562. +        atari_scsi_host->unchecked_isa_dma =
  8563. +        atari_scsi_host->hostt->unchecked_isa_dma = 1;
  8564. +#if I_HAVE_OVERRUNS == 3
  8565. +        atari_scsi_host->sg_tablesize =
  8566. +        atari_scsi_host->hostt->sg_tablesize = SG_NONE;
  8567. +#else
  8568. +        atari_scsi_host->sg_tablesize =
  8569. +        atari_scsi_host->hostt->sg_tablesize = 8;
  8570. +#endif
  8571. +        atari_scsi_host->hostt->cmd_per_lun = 8;
  8572. +    }
  8573. +    
  8574. +    printk( "scsi%d: options CAN_QUEUE=%d CMD_PER_LUN=%d SCATTERGATHER=%d",
  8575. +            instance->host_no, instance->hostt->can_queue,
  8576. +            instance->hostt->cmd_per_lun,
  8577. +            instance->hostt->sg_tablesize );
  8578. +    NCR5380_print_options (instance);
  8579. +    printk ("\n");
  8580. +
  8581. +    called = 1;
  8582. +
  8583. +    return( 1 );
  8584. +}
  8585. +
  8586. +int atari_scsi_reset( Scsi_Cmnd *cmd )
  8587. +
  8588. +{    int        rv;
  8589. +    
  8590. +    /* For doing the reset, SCSI interrupts must be disabled first,
  8591. +     * since the 5380 raises its IRQ line while _RST is active and we
  8592. +     * can't disable interrupts completely, since we need the timer.
  8593. +     */
  8594. +    
  8595. +    if (IS_A_TT())
  8596. +        tt_mfp.int_en_a &= ~0x80;
  8597. +    else
  8598. +        mfp.int_en_b &= ~0x80;
  8599. +    
  8600. +    rv = NCR5380_reset( cmd );
  8601. +
  8602. +    /* Re-enable ints and abort a maybe active DMA transfer */
  8603. +    if (IS_A_TT()) {
  8604. +#ifdef REAL_DMA
  8605. +        tt_scsi_dma.dma_ctrl = 0;
  8606. +#endif /* REAL_DMA */
  8607. +        tt_mfp.int_en_a |= 0x80;
  8608. +    }
  8609. +    else {
  8610. +#ifdef REAL_DMA
  8611. +        st_dma.dma_mode_status = 0x90;
  8612. +        atari_dma_active = 0;
  8613. +#endif /* REAL_DMA */
  8614. +        mfp.int_en_b |= 0x80;
  8615. +    }
  8616. +
  8617. +    return( rv );
  8618. +}
  8619. +
  8620. +    
  8621. +const char * atari_scsi_info( void )
  8622. +
  8623. +{    /* atari_scsi_detect() is verbose enough... */
  8624. +    static const char string[] = "";
  8625. +    return string;
  8626. +}
  8627. +
  8628. +
  8629. +#if defined(REAL_DMA) || defined(REAL_DMA_POLL) || defined(PSEUDO_DMA)
  8630. +
  8631. +unsigned long atari_scsi_dma_setup( struct Scsi_Host *instance, void *data,
  8632. +                                    unsigned long count, int dir )
  8633. +{
  8634. +    unsigned long addr = VTOP( data ),
  8635. +                  cando = atari_dma_xfer_len( count );
  8636. +
  8637. +#if (NDEBUG & NDEBUG_DMA)
  8638. +    printk ("scsi%d: setting up dma, data = %p, phys = %lx, count = %ld, cando = %ld, dir = %d\n",
  8639. +            instance->host_no, data, addr, count, cando, dir);
  8640. +#endif
  8641. +
  8642. +    atari_dma_startaddr = addr;    /* Needed for calculating residual later. */
  8643. +  
  8644. +    if (dir)
  8645. +        /* write: push any dirty cache out before sending it to the
  8646. +         * peripheral. (Must be done before DMA setup, since at least the
  8647. +         * ST-DMA begins to fill internal buffers right after setup.
  8648. +         */
  8649. +        cache_push( addr, cando );
  8650. +    else
  8651. +        /* read: invalidate any cache, may be altered after DMA without CPU
  8652. +         * knowledge
  8653. +         */
  8654. +        cache_clear( addr, cando );
  8655. +
  8656. +    if (cando == 0)
  8657. +        printk( "SCSI warning: DMA programed for 0 bytes !\n" );
  8658. +
  8659. +    if (IS_A_TT()) {
  8660. +    
  8661. +        tt_scsi_dma.dma_ctrl = dir;
  8662. +        SCSI_DMA_WRITE_P( dma_addr_hi, addr );
  8663. +        SCSI_DMA_WRITE_P( dma_cnt_hi, cando );
  8664. +        tt_scsi_dma.dma_ctrl = dir | 2;
  8665. +    }
  8666. +    else { /* ! IS_A_TT */
  8667. +  
  8668. +        /* set address */
  8669. +        SCSI_DMA_SETADR( addr );
  8670. +
  8671. +        /* toggle direction bit to clear FIFO and set DMA direction */
  8672. +        dir <<= 8;
  8673. +        st_dma.dma_mode_status = 0x90 | dir;
  8674. +        st_dma.dma_mode_status = 0x90 | (dir ^ 0x100);
  8675. +        st_dma.dma_mode_status = 0x90 | dir;
  8676. +        udelay(40);
  8677. +        st_dma.fdc_acces_seccount = cando >> 9;
  8678. +        udelay(40);
  8679. +        st_dma.dma_mode_status = 0x10 | dir;
  8680. +        udelay(40);
  8681. +        /* need not restore value of dir, only boolean value is tested */
  8682. +        atari_dma_active = 1;
  8683. +    }
  8684. +    
  8685. +    return( cando );
  8686. +}
  8687. +
  8688. +
  8689. +static long atari_scsi_dma_residual( struct Scsi_Host *instance )
  8690. +
  8691. +{
  8692. +    return( atari_dma_residual );
  8693. +}
  8694. +
  8695. +/* This function calculates the number of bytes that can be transferred
  8696. + * via DMA. On the TT, this is arbitrary, but on the Falcon we have to use
  8697. + * the ST-DMA chip. There are only multiples of 512 bytes possible and
  8698. + * max. 256*512 bytes :-( This means also, that defining READ_OVERRUNS is
  8699. + * not possible, since that would require to program the DMA for n*512 - 2
  8700. + * bytes.
  8701. + */
  8702. +
  8703. +static unsigned long atari_dma_xfer_len( unsigned long wanted_len )
  8704. +
  8705. +{
  8706. +    unsigned long    possible_len;
  8707. +
  8708. +    if (IS_A_TT())
  8709. +        /* TT SCSI DMA can transfer arbitrary #bytes */
  8710. +        return( wanted_len );
  8711. +    
  8712. +    /* ST DMA chip is stupid -- only multiples of 512 bytes! (and max.
  8713. +     * 255*512 bytes, but this should be enough)
  8714. +     */
  8715. +    possible_len =wanted_len & ~0x1ff;
  8716. +    if (possible_len > 255*512)
  8717. +        possible_len = 255*512;
  8718. +
  8719. +#if (NDEBUG & NDEBUG_DMA)
  8720. +    if (possible_len != wanted_len)
  8721. +        printk( "Sorry, must cut DMA transfer size to %ld bytes instead of %ld\n",
  8722. +                possible_len, wanted_len );
  8723. +#endif
  8724. +
  8725. +    return( possible_len );
  8726. +}
  8727. +
  8728. +
  8729. +#endif    /* REAL_DMA || REAL_DMA_POLL || PSEUDO_DMA */
  8730. +
  8731. +
  8732. +/* NCR5380 register access functions
  8733. + *
  8734. + * There are seperate functions for TT and Falcon, because the access
  8735. + * methods are quite different. The calling macros NCR5380_read and
  8736. + * NCR5380_write call these functions via function pointers.
  8737. + */
  8738. +
  8739. +static unsigned char atari_scsi_tt_reg_read( unsigned char reg )
  8740. +
  8741. +{
  8742. +    return( tt_scsi_regp[reg * 2] );
  8743. +}
  8744. +
  8745. +static void atari_scsi_tt_reg_write( unsigned char reg, unsigned char value )
  8746. +
  8747. +{
  8748. +    tt_scsi_regp[reg * 2] = value;
  8749. +}
  8750. +
  8751. +static unsigned char atari_scsi_falcon_reg_read( unsigned char reg )
  8752. +
  8753. +{
  8754. +    dma_wd.dma_mode_status= (u_short)(0x88 + reg);
  8755. +    return( (u_char)dma_wd.fdc_acces_seccount );
  8756. +}
  8757. +
  8758. +static void atari_scsi_falcon_reg_write( unsigned char reg, unsigned char value )
  8759. +
  8760. +{
  8761. +    dma_wd.dma_mode_status = (u_short)(0x88 + reg);
  8762. +    dma_wd.fdc_acces_seccount = (u_short)value;
  8763. +}
  8764. +
  8765. +
  8766. +#include "atari_NCR5380.c"
  8767. +
  8768. +#endif /* CONFIG_ATARI_*_SCSI */
  8769. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/drivers/scsi/scsi.c linux-0.9pl4/drivers/scsi/scsi.c
  8770. --- linux-0.9pl3/drivers/scsi/scsi.c    Sun Aug 14 10:30:49 1994
  8771. +++ linux-0.9pl4/drivers/scsi/scsi.c    Mon Nov  7 22:30:18 1994
  8772. @@ -26,7 +26,7 @@
  8773.  #include "constants.h"
  8774.  
  8775.  /*
  8776. -static const char RCSid[] = "$Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/scsi.c,v 1.5 1993/09/24 12:45:18 drew Exp drew $";
  8777. +static const char RCSid[] = "$Header: /var/src/linux-0.9pl4/drivers/scsi/RCS/scsi.c,v 1.1 1994/11/08 03:29:28 hamish Exp hamish $";
  8778.  */
  8779.  
  8780.  /* Command groups 3 and 4 are reserved and should never be used.  */
  8781. @@ -603,13 +603,13 @@
  8782.        SCpnt->request.nr_sectors -= req->nr_sectors;
  8783.        req->current_nr_sectors = bh->b_size >> 9;
  8784.        req->buffer = bh->b_data;
  8785. -      SCpnt->request.waiting = NULL; /* Wait until whole thing done */
  8786. +      SCpnt->request.sem = NULL; /* Wait until whole thing done */
  8787.      } else
  8788.        req->dev = -1;
  8789.        
  8790.    } else {
  8791.      SCpnt->request.dev = 0xffff; /* Busy, but no request */
  8792. -    SCpnt->request.waiting = NULL;  /* And no one is waiting for the device either */
  8793. +    SCpnt->request.sem = NULL;  /* And no one is waiting for the device either */
  8794.    };
  8795.  
  8796.    SCpnt->use_sg = 0;  /* Reset the scatter-gather flag */
  8797. @@ -701,7 +701,7 @@
  8798.          SCpnt->request.nr_sectors -= req->nr_sectors;
  8799.          req->current_nr_sectors = bh->b_size >> 9;
  8800.          req->buffer = bh->b_data;
  8801. -        SCpnt->request.waiting = NULL; /* Wait until whole thing done */
  8802. +        SCpnt->request.sem = NULL; /* Wait until whole thing done */
  8803.        }
  8804.        else 
  8805.          {
  8806. @@ -710,7 +710,7 @@
  8807.          };
  8808.      } else {
  8809.        SCpnt->request.dev = 0xffff; /* Busy */
  8810. -      SCpnt->request.waiting = NULL;  /* And no one is waiting for this to complete */
  8811. +      SCpnt->request.sem = NULL;  /* And no one is waiting for this to complete */
  8812.      };
  8813.      restore_flags (flags);
  8814.      break;
  8815. @@ -1501,7 +1501,10 @@
  8816.  
  8817.      if(SCset){
  8818.        oldto = SCset->timeout - used;
  8819. +    if(timeout)
  8820.        SCset->timeout = timeout + used;
  8821. +    else
  8822. +      SCset->timeout = 0;
  8823.      };
  8824.  
  8825.      least = 0xffffffff;
  8826. @@ -1667,6 +1670,7 @@
  8827.            SCpnt->host = scsi_devices[i].host;
  8828.            SCpnt->target = scsi_devices[i].id;
  8829.            SCpnt->lun = scsi_devices[i].lun;
  8830. +          SCpnt->timeout = 0;
  8831.            SCpnt->index = i;
  8832.            SCpnt->request.dev = -1; /* Mark not busy */
  8833.            SCpnt->use_sg = 0;
  8834. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/drivers/scsi/scsi.h linux-0.9pl4/drivers/scsi/scsi.h
  8835. --- linux-0.9pl3/drivers/scsi/scsi.h    Sun Aug 14 10:30:46 1994
  8836. +++ linux-0.9pl4/drivers/scsi/scsi.h    Sat Nov  5 11:41:45 1994
  8837. @@ -452,7 +452,6 @@
  8838.  {
  8839.      struct request * req;
  8840.      struct buffer_head * bh;
  8841. -    struct task_struct * p;
  8842.  
  8843.      req = &SCpnt->request;
  8844.      req->errors = 0;
  8845. @@ -484,11 +483,8 @@
  8846.        return;
  8847.      };
  8848.      DEVICE_OFF(req->dev);
  8849. -    if ((p = req->waiting) != NULL) {
  8850. -        req->waiting = NULL;
  8851. -        p->state = TASK_RUNNING;
  8852. -        if (p->counter > current->counter)
  8853. -            need_resched = 1;
  8854. +    if (req->sem != NULL) {
  8855. +        up(req->sem);
  8856.      }
  8857.      req->dev = -1;
  8858.      wake_up(&scsi_devices[SCpnt->index].device_wait);
  8859. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/drivers/scsi/scsi_ioctl.c linux-0.9pl4/drivers/scsi/scsi_ioctl.c
  8860. --- linux-0.9pl3/drivers/scsi/scsi_ioctl.c    Sun Aug 14 10:30:49 1994
  8861. +++ linux-0.9pl4/drivers/scsi/scsi_ioctl.c    Sat Nov  5 11:50:28 1994
  8862. @@ -72,16 +72,12 @@
  8863.  static void scsi_ioctl_done (Scsi_Cmnd * SCpnt)
  8864.  {
  8865.    struct request * req;
  8866. -  struct task_struct * p;
  8867.  
  8868.    req = &SCpnt->request;
  8869.    req->dev = 0xfffe; /* Busy, but indicate request done */
  8870.  
  8871. -  if ((p = req->waiting) != NULL) {
  8872. -    req->waiting = NULL;
  8873. -    p->state = TASK_RUNNING;
  8874. -    if (p->counter > current->counter)
  8875. -      need_resched = 1;
  8876. +  if (req->sem != NULL) {
  8877. +    up(req->sem);
  8878.    }
  8879.  }
  8880.  
  8881. @@ -96,8 +92,10 @@
  8882.              MAX_RETRIES);
  8883.  
  8884.      if (SCpnt->request.dev != 0xfffe){
  8885. -      SCpnt->request.waiting = current;
  8886. -      current->state = TASK_UNINTERRUPTIBLE;
  8887. +      struct semaphore sem = MUTEX_LOCKED;
  8888. +      SCpnt->request.sem = &sem;
  8889. +      down(&sem);
  8890. +      /* Hmm.. Have to ask about this one */
  8891.        while (SCpnt->request.dev != 0xfffe) schedule();
  8892.      };
  8893.  
  8894. @@ -146,7 +144,7 @@
  8895.      Scsi_Cmnd * SCpnt;
  8896.      unsigned char opcode;
  8897.      int inlen, outlen, cmdlen;
  8898. -    int needed;
  8899. +    int needed, buf_needed;
  8900.      int result;
  8901.  
  8902.      if (!buffer)
  8903. @@ -158,11 +156,11 @@
  8904.      cmd_in = (char *) ( ((int *)buffer) + 2);
  8905.      opcode = get_fs_byte(cmd_in);
  8906.  
  8907. -    needed = (inlen > outlen ? inlen : outlen);
  8908. -    if(needed){
  8909. -      needed = (needed + 511) & ~511;
  8910. -      if (needed > MAX_BUF) needed = MAX_BUF;
  8911. -      buf = (char *) scsi_malloc(needed);
  8912. +    needed = buf_needed = (inlen > outlen ? inlen : outlen);
  8913. +    if(buf_needed){
  8914. +      buf_needed = (buf_needed + 511) & ~511;
  8915. +      if (buf_needed > MAX_BUF) buf_needed = MAX_BUF;
  8916. +      buf = (char *) scsi_malloc(buf_needed);
  8917.        if (!buf) return -ENOMEM;
  8918.      } else
  8919.        buf = NULL;
  8920. @@ -180,8 +178,10 @@
  8921.              MAX_RETRIES);
  8922.  
  8923.      if (SCpnt->request.dev != 0xfffe){
  8924. -      SCpnt->request.waiting = current;
  8925. -      current->state = TASK_UNINTERRUPTIBLE;
  8926. +      struct semaphore sem = MUTEX_LOCKED;
  8927. +      SCpnt->request.sem = &sem;
  8928. +      down(&sem);
  8929. +      /* Hmm.. Have to ask about this one */
  8930.        while (SCpnt->request.dev != 0xfffe) schedule();
  8931.      };
  8932.  
  8933. @@ -201,7 +201,7 @@
  8934.      };
  8935.      result = SCpnt->result;
  8936.      SCpnt->request.dev = -1;  /* Mark as not busy */
  8937. -    if (buf) scsi_free(buf, needed);
  8938. +    if (buf) scsi_free(buf, buf_needed);
  8939.      wake_up(&scsi_devices[SCpnt->index].device_wait);
  8940.      return result;
  8941.  #else
  8942. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/drivers/scsi/sd.c linux-0.9pl4/drivers/scsi/sd.c
  8943. --- linux-0.9pl3/drivers/scsi/sd.c    Sun Aug 14 10:30:50 1994
  8944. +++ linux-0.9pl4/drivers/scsi/sd.c    Sat Nov  5 11:41:47 1994
  8945. @@ -652,16 +652,12 @@
  8946.  static void sd_init_done (Scsi_Cmnd * SCpnt)
  8947.  {
  8948.    struct request * req;
  8949. -  struct task_struct * p;
  8950.  
  8951.    req = &SCpnt->request;
  8952.    req->dev = 0xfffe; /* Busy, but indicate request done */
  8953.  
  8954. -  if ((p = req->waiting) != NULL) {
  8955. -    req->waiting = NULL;
  8956. -    p->state = TASK_RUNNING;
  8957. -    if (p->counter > current->counter)
  8958. -      need_resched = 1;
  8959. +  if (req->sem != NULL) {
  8960. +    up(req->sem);
  8961.    }
  8962.  }
  8963.  
  8964. @@ -766,8 +762,10 @@
  8965.        while(SCpnt->request.dev != 0xfffe);
  8966.      else
  8967.        if (SCpnt->request.dev != 0xfffe){
  8968. -    SCpnt->request.waiting = current;
  8969. -    current->state = TASK_UNINTERRUPTIBLE;
  8970. +          struct semaphore sem = MUTEX_LOCKED;
  8971. +    SCpnt->request.sem = &sem;
  8972. +    down(&sem);
  8973. +    /* Hmm.. Have to ask about this one.. */
  8974.      while (SCpnt->request.dev != 0xfffe) schedule();
  8975.        };
  8976.  
  8977. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/drivers/scsi/sr.c linux-0.9pl4/drivers/scsi/sr.c
  8978. --- linux-0.9pl3/drivers/scsi/sr.c    Sun Aug 14 10:30:50 1994
  8979. +++ linux-0.9pl4/drivers/scsi/sr.c    Sat Nov  5 11:41:46 1994
  8980. @@ -634,16 +634,12 @@
  8981.  static void sr_init_done (Scsi_Cmnd * SCpnt)
  8982.  {
  8983.    struct request * req;
  8984. -  struct task_struct * p;
  8985.    
  8986.    req = &SCpnt->request;
  8987.    req->dev = 0xfffe; /* Busy, but indicate request done */
  8988.    
  8989. -  if ((p = req->waiting) != NULL) {
  8990. -    req->waiting = NULL;
  8991. -    p->state = TASK_RUNNING;
  8992. -    if (p->counter > current->counter)
  8993. -      need_resched = 1;
  8994. +  if (req->sem != NULL) {
  8995. +    up(req->sem);
  8996.    }
  8997.  }
  8998.  
  8999. @@ -673,8 +669,10 @@
  9000.        while(SCpnt->request.dev != 0xfffe);
  9001.      else
  9002.        if (SCpnt->request.dev != 0xfffe){
  9003. -    SCpnt->request.waiting = current;
  9004. -    current->state = TASK_UNINTERRUPTIBLE;
  9005. +          struct semaphore sem = MUTEX_LOCKED;
  9006. +    SCpnt->request.sem = &sem;
  9007. +    down(&sem);
  9008. +    /* Hmm.. Have to ask about this */
  9009.      while (SCpnt->request.dev != 0xfffe) schedule();
  9010.        };
  9011.      
  9012. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/drivers/scsi/sr_ioctl.c linux-0.9pl4/drivers/scsi/sr_ioctl.c
  9013. --- linux-0.9pl3/drivers/scsi/sr_ioctl.c    Sun Aug 14 10:30:49 1994
  9014. +++ linux-0.9pl4/drivers/scsi/sr_ioctl.c    Sat Nov  5 11:41:48 1994
  9015. @@ -21,16 +21,12 @@
  9016.  static void sr_ioctl_done(Scsi_Cmnd * SCpnt)
  9017.  {
  9018.    struct request * req;
  9019. -  struct task_struct * p;
  9020.    
  9021.    req = &SCpnt->request;
  9022.    req->dev = 0xfffe; /* Busy, but indicate request done */
  9023.    
  9024. -  if ((p = req->waiting) != NULL) {
  9025. -    req->waiting = NULL;
  9026. -    p->state = TASK_RUNNING;
  9027. -    if (p->counter > current->counter)
  9028. -      need_resched = 1;
  9029. +  if (req->sem != NULL) {
  9030. +    up(req->sem);
  9031.    }
  9032.  }
  9033.  
  9034. @@ -50,8 +46,10 @@
  9035.  
  9036.  
  9037.      if (SCpnt->request.dev != 0xfffe){
  9038. -      SCpnt->request.waiting = current;
  9039. -      current->state = TASK_UNINTERRUPTIBLE;
  9040. +      struct semaphore sem = MUTEX_LOCKED;
  9041. +      SCpnt->request.sem = &sem;
  9042. +      down(&sem);
  9043. +      /* Hmm.. Have to ask about this */
  9044.        while (SCpnt->request.dev != 0xfffe) schedule();
  9045.      };
  9046.  
  9047. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/fs/buffer.c linux-0.9pl4/fs/buffer.c
  9048. --- linux-0.9pl3/fs/buffer.c    Sun Aug 14 10:29:52 1994
  9049. +++ linux-0.9pl4/fs/buffer.c    Mon Nov  7 22:31:29 1994
  9050. @@ -48,6 +48,10 @@
  9051.  #ifdef CONFIG_MCD
  9052.  extern int check_mcd_media_change(int, int);
  9053.  #endif
  9054. +#ifdef CONFIG_ATARI_ACSI
  9055. +extern int check_acsi_media_change(int, int);
  9056. +extern int revalidate_acsidisk(int, int);
  9057. +#endif
  9058.  
  9059.  static int grow_buffers(int pri, int size);
  9060.  
  9061. @@ -257,6 +261,12 @@
  9062.          break;
  9063.  #endif
  9064.  
  9065. +#if defined(CONFIG_ATARI_ACSI)
  9066. +         case ACSI_MAJOR:
  9067. +        i = check_acsi_media_change(dev, 0);
  9068. +        break;
  9069. +#endif
  9070. +
  9071.       default:
  9072.          return;
  9073.      };
  9074. @@ -276,6 +286,11 @@
  9075.     all of the partitions that lie on the disk. */
  9076.      if (MAJOR(dev) == SCSI_DISK_MAJOR)
  9077.          revalidate_scsidisk(dev, 0);
  9078. +#endif
  9079. +#if defined(CONFIG_ATARI_ACSI)
  9080. +/* The same is true for ACSI removable harddisks... */
  9081. +    if (MAJOR(dev) == ACSI_MAJOR)
  9082. +        revalidate_acsidisk(dev, 0);
  9083.  #endif
  9084.  }
  9085.  
  9086. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/fs/minix/symlink.c linux-0.9pl4/fs/minix/symlink.c
  9087. --- linux-0.9pl3/fs/minix/symlink.c    Tue Sep 27 22:22:40 1994
  9088. +++ linux-0.9pl4/fs/minix/symlink.c    Mon Oct 10 16:47:50 1994
  9089. @@ -101,7 +101,6 @@
  9090.          i++;
  9091.          put_fs_byte(c,buffer++);
  9092.      }
  9093. -    put_fs_byte(0,buffer++); /* mark EOS */
  9094.      brelse(bh);
  9095.      return i;
  9096.  }
  9097. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/fs/nfs/Makefile linux-0.9pl4/fs/nfs/Makefile
  9098. --- linux-0.9pl3/fs/nfs/Makefile    Wed Dec 31 19:00:00 1969
  9099. +++ linux-0.9pl4/fs/nfs/Makefile    Mon Oct 10 16:48:25 1994
  9100. @@ -0,0 +1,27 @@
  9101. +#
  9102. +# Makefile for the linux nfs-filesystem routines.
  9103. +#
  9104. +# Note! Dependencies are done automagically by 'make dep', which also
  9105. +# removes any old dependencies. DON'T put your own dependencies here
  9106. +# unless it's something special (ie not a .c file).
  9107. +#
  9108. +# Note 2! The CFLAGS definitions are now in the main makefile...
  9109. +
  9110. +include ../../.config
  9111. +include ../../MakeVars
  9112. +
  9113. +OBJS=    proc.o sock.o inode.o file.o dir.o \
  9114. +    symlink.o mmap.o
  9115. +
  9116. +nfs.o: $(OBJS)
  9117. +    $(LD) -r -o nfs.o $(OBJS)
  9118. +
  9119. +dep:
  9120. +    $(CPP) -M *.c > .depend
  9121. +
  9122. +#
  9123. +# include a dependency file if one exists
  9124. +#
  9125. +ifeq (.depend,$(wildcard .depend))
  9126. +include .depend
  9127. +endif
  9128. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/fs/nfs/dir.c linux-0.9pl4/fs/nfs/dir.c
  9129. --- linux-0.9pl3/fs/nfs/dir.c    Wed Dec 31 19:00:00 1969
  9130. +++ linux-0.9pl4/fs/nfs/dir.c    Wed Dec  1 07:44:15 1993
  9131. @@ -0,0 +1,606 @@
  9132. +/*
  9133. + *  linux/fs/nfs/dir.c
  9134. + *
  9135. + *  Copyright (C) 1992  Rick Sladkey
  9136. + *
  9137. + *  nfs directory handling functions
  9138. + */
  9139. +
  9140. +#include <linux/sched.h>
  9141. +#include <linux/errno.h>
  9142. +#include <linux/stat.h>
  9143. +#include <linux/nfs_fs.h>
  9144. +#include <linux/fcntl.h>
  9145. +#include <linux/string.h>
  9146. +#include <linux/kernel.h>
  9147. +#include <linux/malloc.h>
  9148. +#include <linux/mm.h>
  9149. +
  9150. +#include <asm/segment.h>    /* for fs functions */
  9151. +
  9152. +static int nfs_dir_read(struct inode *, struct file *filp, char *buf,
  9153. +            int count);
  9154. +static int nfs_readdir(struct inode *, struct file *, struct dirent *, int);
  9155. +static int nfs_lookup(struct inode *dir, const char *name, int len,
  9156. +              struct inode **result);
  9157. +static int nfs_create(struct inode *dir, const char *name, int len, int mode,
  9158. +              struct inode **result);
  9159. +static int nfs_mkdir(struct inode *dir, const char *name, int len, int mode);
  9160. +static int nfs_rmdir(struct inode *dir, const char *name, int len);
  9161. +static int nfs_unlink(struct inode *dir, const char *name, int len);
  9162. +static int nfs_symlink(struct inode *inode, const char *name, int len,
  9163. +               const char *symname);
  9164. +static int nfs_link(struct inode *oldinode, struct inode *dir,
  9165. +            const char *name, int len);
  9166. +static int nfs_mknod(struct inode *dir, const char *name, int len, int mode,
  9167. +             int rdev);
  9168. +static int nfs_rename(struct inode *old_dir, const char *old_name,
  9169. +              int old_len, struct inode *new_dir, const char *new_name,
  9170. +              int new_len);
  9171. +
  9172. +static struct file_operations nfs_dir_operations = {
  9173. +    NULL,            /* lseek - default */
  9174. +    nfs_dir_read,        /* read - bad */
  9175. +    NULL,            /* write - bad */
  9176. +    nfs_readdir,        /* readdir */
  9177. +    NULL,            /* select - default */
  9178. +    NULL,            /* ioctl - default */
  9179. +    NULL,            /* mmap */
  9180. +    NULL,            /* no special open code */
  9181. +    NULL,            /* no special release code */
  9182. +    NULL            /* fsync */
  9183. +};
  9184. +
  9185. +struct inode_operations nfs_dir_inode_operations = {
  9186. +    &nfs_dir_operations,    /* default directory file-ops */
  9187. +    nfs_create,        /* create */
  9188. +    nfs_lookup,        /* lookup */
  9189. +    nfs_link,        /* link */
  9190. +    nfs_unlink,        /* unlink */
  9191. +    nfs_symlink,        /* symlink */
  9192. +    nfs_mkdir,        /* mkdir */
  9193. +    nfs_rmdir,        /* rmdir */
  9194. +    nfs_mknod,        /* mknod */
  9195. +    nfs_rename,        /* rename */
  9196. +    NULL,            /* readlink */
  9197. +    NULL,            /* follow_link */
  9198. +    NULL,            /* bmap */
  9199. +    NULL,            /* truncate */
  9200. +    NULL            /* permission */
  9201. +};
  9202. +
  9203. +static int nfs_dir_read(struct inode *inode, struct file *filp, char *buf,
  9204. +            int count)
  9205. +{
  9206. +    return -EISDIR;
  9207. +}
  9208. +
  9209. +/*
  9210. + * We need to do caching of directory entries to prevent an
  9211. + * incredible amount of RPC traffic.  Only the most recent open
  9212. + * directory is cached.  This seems sufficient for most purposes.
  9213. + * Technically, we ought to flush the cache on close but this is
  9214. + * not a problem in practice.
  9215. + */
  9216. +
  9217. +static int nfs_readdir(struct inode *inode, struct file *filp,
  9218. +               struct dirent *dirent, int count)
  9219. +{
  9220. +    static int c_dev = 0;
  9221. +    static int c_ino;
  9222. +    static int c_size;
  9223. +    static struct nfs_entry *c_entry = NULL;
  9224. +
  9225. +    int result;
  9226. +    int i;
  9227. +    struct nfs_entry *entry;
  9228. +
  9229. +    if (!inode || !S_ISDIR(inode->i_mode)) {
  9230. +        printk("nfs_readdir: inode is NULL or not a directory\n");
  9231. +        return -EBADF;
  9232. +    }
  9233. +
  9234. +    /* initialize cache memory if it hasn't been used before */
  9235. +
  9236. +    if (c_entry == NULL) {
  9237. +        i = sizeof (struct nfs_entry)*NFS_READDIR_CACHE_SIZE;
  9238. +        c_entry = (struct nfs_entry *) kmalloc(i, GFP_KERNEL);
  9239. +        for (i = 0; i < NFS_READDIR_CACHE_SIZE; i++) {
  9240. +            c_entry[i].name = (char *) kmalloc(NFS_MAXNAMLEN + 1,
  9241. +                GFP_KERNEL);
  9242. +        }
  9243. +    }
  9244. +    entry = NULL;
  9245. +
  9246. +    /* try to find it in the cache */
  9247. +
  9248. +    if (inode->i_dev == c_dev && inode->i_ino == c_ino) {
  9249. +        for (i = 0; i < c_size; i++) {
  9250. +            if (filp->f_pos == c_entry[i].cookie) {
  9251. +                if (i == c_size - 1) {
  9252. +                    if (c_entry[i].eof)
  9253. +                        return 0;
  9254. +                }
  9255. +                else
  9256. +                    entry = c_entry + i + 1;
  9257. +                break;
  9258. +            }
  9259. +        }
  9260. +    }
  9261. +
  9262. +    /* if we didn't find it in the cache, revert to an nfs call */
  9263. +
  9264. +    if (!entry) {
  9265. +        result = nfs_proc_readdir(NFS_SERVER(inode), NFS_FH(inode),
  9266. +            filp->f_pos, NFS_READDIR_CACHE_SIZE, c_entry);
  9267. +        if (result < 0) {
  9268. +            c_dev = 0;
  9269. +            return result;
  9270. +        }
  9271. +        if (result > 0) {
  9272. +            c_dev = inode->i_dev;
  9273. +            c_ino = inode->i_ino;
  9274. +            c_size = result;
  9275. +            entry = c_entry + 0;
  9276. +        }
  9277. +    }
  9278. +
  9279. +    /* if we found it in the cache or from an nfs call, return results */
  9280. +
  9281. +    if (entry) {
  9282. +        i = strlen(entry->name);
  9283. +        memcpy_tofs(dirent->d_name, entry->name, i + 1);
  9284. +        put_fs_long(entry->fileid, &dirent->d_ino);
  9285. +        put_fs_word(i, &dirent->d_reclen);
  9286. +        filp->f_pos = entry->cookie;
  9287. +        return i;
  9288. +    }
  9289. +    return 0;
  9290. +}
  9291. +
  9292. +/*
  9293. + * Lookup caching is a big win for performance but this is just
  9294. + * a trial to see how well it works on a small scale.
  9295. + * For example, bash does a lookup on ".." 13 times for each path
  9296. + * element when running pwd.  Yes, hard to believe but true.
  9297. + * Try pwd in a filesystem mounted with noac.
  9298. + *
  9299. + * It trades a little cpu time and memory for a lot of network bandwidth.
  9300. + * Since the cache is not hashed yet, it is a good idea not to make it too
  9301. + * large because every lookup looks through the entire cache even
  9302. + * though most of them will fail.
  9303. + */
  9304. +
  9305. +static struct nfs_lookup_cache_entry {
  9306. +    int dev;
  9307. +    int inode;
  9308. +    char filename[NFS_MAXNAMLEN + 1];
  9309. +    struct nfs_fh fhandle;
  9310. +    struct nfs_fattr fattr;
  9311. +    int expiration_date;
  9312. +} nfs_lookup_cache[NFS_LOOKUP_CACHE_SIZE];
  9313. +
  9314. +static struct nfs_lookup_cache_entry *nfs_lookup_cache_index(struct inode *dir,
  9315. +                                 const char *filename)
  9316. +{
  9317. +    struct nfs_lookup_cache_entry *entry;
  9318. +    int i;
  9319. +
  9320. +    for (i = 0; i < NFS_LOOKUP_CACHE_SIZE; i++) {
  9321. +        entry = nfs_lookup_cache + i;
  9322. +        if (entry->dev == dir->i_dev && entry->inode == dir->i_ino
  9323. +            && !strncmp(filename, entry->filename, NFS_MAXNAMLEN))
  9324. +            return entry;
  9325. +    }
  9326. +    return NULL;
  9327. +}
  9328. +
  9329. +static int nfs_lookup_cache_lookup(struct inode *dir, const char *filename,
  9330. +                   struct nfs_fh *fhandle,
  9331. +                   struct nfs_fattr *fattr)
  9332. +{
  9333. +    static int nfs_lookup_cache_in_use = 0;
  9334. +
  9335. +    struct nfs_lookup_cache_entry *entry;
  9336. +
  9337. +    if (!nfs_lookup_cache_in_use) {
  9338. +        memset(nfs_lookup_cache, 0, sizeof(nfs_lookup_cache));
  9339. +        nfs_lookup_cache_in_use = 1;
  9340. +    }
  9341. +    if ((entry = nfs_lookup_cache_index(dir, filename))) {
  9342. +        if (jiffies > entry->expiration_date) {
  9343. +            entry->dev = 0;
  9344. +            return 0;
  9345. +        }
  9346. +        *fhandle = entry->fhandle;
  9347. +        *fattr = entry->fattr;
  9348. +        return 1;
  9349. +    }
  9350. +    return 0;
  9351. +}
  9352. +
  9353. +static void nfs_lookup_cache_add(struct inode *dir, const char *filename,
  9354. +                 struct nfs_fh *fhandle,
  9355. +                 struct nfs_fattr *fattr)
  9356. +{
  9357. +    static int nfs_lookup_cache_pos = 0;
  9358. +    struct nfs_lookup_cache_entry *entry;
  9359. +
  9360. +    /* compensate for bug in SGI NFS server */
  9361. +    if (fattr->size == -1 || fattr->uid == -1 || fattr->gid == -1
  9362. +        || fattr->atime.seconds == -1 || fattr->mtime.seconds == -1)
  9363. +        return;
  9364. +    if (!(entry = nfs_lookup_cache_index(dir, filename))) {
  9365. +        entry = nfs_lookup_cache + nfs_lookup_cache_pos++;
  9366. +        if (nfs_lookup_cache_pos == NFS_LOOKUP_CACHE_SIZE)
  9367. +            nfs_lookup_cache_pos = 0;
  9368. +    }
  9369. +    entry->dev = dir->i_dev;
  9370. +    entry->inode = dir->i_ino;
  9371. +    strcpy(entry->filename, filename);
  9372. +    entry->fhandle = *fhandle;
  9373. +    entry->fattr = *fattr;
  9374. +    entry->expiration_date = jiffies + (S_ISDIR(fattr->mode)
  9375. +        ? NFS_SERVER(dir)->acdirmax : NFS_SERVER(dir)->acregmax);
  9376. +}
  9377. +
  9378. +static void nfs_lookup_cache_remove(struct inode *dir, struct inode *inode,
  9379. +                    const char *filename)
  9380. +{
  9381. +    struct nfs_lookup_cache_entry *entry;
  9382. +    int dev;
  9383. +    int fileid;
  9384. +    int i;
  9385. +
  9386. +    if (inode) {
  9387. +        dev = inode->i_dev;
  9388. +        fileid = inode->i_ino;
  9389. +    }
  9390. +    else if ((entry = nfs_lookup_cache_index(dir, filename))) {
  9391. +        dev = entry->dev;
  9392. +        fileid = entry->fattr.fileid;
  9393. +    }
  9394. +    else
  9395. +        return;
  9396. +    for (i = 0; i < NFS_LOOKUP_CACHE_SIZE; i++) {
  9397. +        entry = nfs_lookup_cache + i;
  9398. +        if (entry->dev == dev && entry->fattr.fileid == fileid)
  9399. +            entry->dev = 0;
  9400. +    }
  9401. +}
  9402. +
  9403. +static void nfs_lookup_cache_refresh(struct inode *file,
  9404. +                     struct nfs_fattr *fattr)
  9405. +{
  9406. +    struct nfs_lookup_cache_entry *entry;
  9407. +    int dev = file->i_dev;
  9408. +    int fileid = file->i_ino;
  9409. +    int i;
  9410. +
  9411. +    for (i = 0; i < NFS_LOOKUP_CACHE_SIZE; i++) {
  9412. +        entry = nfs_lookup_cache + i;
  9413. +        if (entry->dev == dev && entry->fattr.fileid == fileid)
  9414. +            entry->fattr = *fattr;
  9415. +    }
  9416. +}
  9417. +
  9418. +static int nfs_lookup(struct inode *dir, const char *__name, int len,
  9419. +              struct inode **result)
  9420. +{
  9421. +    struct nfs_fh fhandle;
  9422. +    struct nfs_fattr fattr;
  9423. +    char name[len > NFS_MAXNAMLEN? 1 : len+1];
  9424. +    int error;
  9425. +
  9426. +    *result = NULL;
  9427. +    if (!dir || !S_ISDIR(dir->i_mode)) {
  9428. +        printk("nfs_lookup: inode is NULL or not a directory\n");
  9429. +        iput(dir);
  9430. +        return -ENOENT;
  9431. +    }
  9432. +    if (len > NFS_MAXNAMLEN) {
  9433. +        iput(dir);
  9434. +        return -ENAMETOOLONG;
  9435. +    }
  9436. +    memcpy(name,__name,len);
  9437. +    name[len] = '\0';
  9438. +    if (len == 1 && name[0] == '.') { /* cheat for "." */
  9439. +        *result = dir;
  9440. +        return 0;
  9441. +    }
  9442. +    if ((NFS_SERVER(dir)->flags & NFS_MOUNT_NOAC)
  9443. +        || !nfs_lookup_cache_lookup(dir, name, &fhandle, &fattr)) {
  9444. +        if ((error = nfs_proc_lookup(NFS_SERVER(dir), NFS_FH(dir),
  9445. +            name, &fhandle, &fattr))) {
  9446. +            iput(dir);
  9447. +            return error;
  9448. +        }
  9449. +        nfs_lookup_cache_add(dir, name, &fhandle, &fattr);
  9450. +    }
  9451. +    if (!(*result = nfs_fhget(dir->i_sb, &fhandle, &fattr))) {
  9452. +        iput(dir);
  9453. +        return -EACCES;
  9454. +    }
  9455. +    iput(dir);
  9456. +    return 0;
  9457. +}
  9458. +
  9459. +static int nfs_create(struct inode *dir, const char *name, int len, int mode,
  9460. +              struct inode **result)
  9461. +{
  9462. +    struct nfs_sattr sattr;
  9463. +    struct nfs_fattr fattr;
  9464. +    struct nfs_fh fhandle;
  9465. +    int error;
  9466. +
  9467. +    *result = NULL;
  9468. +    if (!dir || !S_ISDIR(dir->i_mode)) {
  9469. +        printk("nfs_create: inode is NULL or not a directory\n");
  9470. +        iput(dir);
  9471. +        return -ENOENT;
  9472. +    }
  9473. +    if (len > NFS_MAXNAMLEN) {
  9474. +        iput(dir);
  9475. +        return -ENAMETOOLONG;
  9476. +    }
  9477. +    sattr.mode = mode;
  9478. +    sattr.uid = sattr.gid = sattr.size = (unsigned) -1;
  9479. +    sattr.atime.seconds = sattr.mtime.seconds = (unsigned) -1;
  9480. +    if ((error = nfs_proc_create(NFS_SERVER(dir), NFS_FH(dir),
  9481. +        name, &sattr, &fhandle, &fattr))) {
  9482. +        iput(dir);
  9483. +        return error;
  9484. +    }
  9485. +    if (!(*result = nfs_fhget(dir->i_sb, &fhandle, &fattr))) {
  9486. +        iput(dir);
  9487. +        return -EACCES;
  9488. +    }
  9489. +    nfs_lookup_cache_add(dir, name, &fhandle, &fattr);
  9490. +    iput(dir);
  9491. +    return 0;
  9492. +}
  9493. +
  9494. +static int nfs_mknod(struct inode *dir, const char *name, int len,
  9495. +             int mode, int rdev)
  9496. +{
  9497. +    struct nfs_sattr sattr;
  9498. +    struct nfs_fattr fattr;
  9499. +    struct nfs_fh fhandle;
  9500. +    int error;
  9501. +
  9502. +    if (!dir || !S_ISDIR(dir->i_mode)) {
  9503. +        printk("nfs_mknod: inode is NULL or not a directory\n");
  9504. +        iput(dir);
  9505. +        return -ENOENT;
  9506. +    }
  9507. +    if (len > NFS_MAXNAMLEN) {
  9508. +        iput(dir);
  9509. +        return -ENAMETOOLONG;
  9510. +    }
  9511. +    sattr.mode = mode;
  9512. +    sattr.uid = sattr.gid = (unsigned) -1;
  9513. +    if (S_ISCHR(mode) || S_ISBLK(mode))
  9514. +        sattr.size = rdev; /* get out your barf bag */
  9515. +    else
  9516. +        sattr.size = (unsigned) -1;
  9517. +    sattr.atime.seconds = sattr.mtime.seconds = (unsigned) -1;
  9518. +    error = nfs_proc_create(NFS_SERVER(dir), NFS_FH(dir),
  9519. +        name, &sattr, &fhandle, &fattr);
  9520. +    if (!error)
  9521. +        nfs_lookup_cache_add(dir, name, &fhandle, &fattr);
  9522. +    iput(dir);
  9523. +    return error;
  9524. +}
  9525. +
  9526. +static int nfs_mkdir(struct inode *dir, const char *name, int len, int mode)
  9527. +{
  9528. +    struct nfs_sattr sattr;
  9529. +    struct nfs_fattr fattr;
  9530. +    struct nfs_fh fhandle;
  9531. +    int error;
  9532. +
  9533. +    if (!dir || !S_ISDIR(dir->i_mode)) {
  9534. +        printk("nfs_mkdir: inode is NULL or not a directory\n");
  9535. +        iput(dir);
  9536. +        return -ENOENT;
  9537. +    }
  9538. +    if (len > NFS_MAXNAMLEN) {
  9539. +        iput(dir);
  9540. +        return -ENAMETOOLONG;
  9541. +    }
  9542. +    sattr.mode = mode;
  9543. +    sattr.uid = sattr.gid = sattr.size = (unsigned) -1;
  9544. +    sattr.atime.seconds = sattr.mtime.seconds = (unsigned) -1;
  9545. +    error = nfs_proc_mkdir(NFS_SERVER(dir), NFS_FH(dir),
  9546. +        name, &sattr, &fhandle, &fattr);
  9547. +    if (!error)
  9548. +        nfs_lookup_cache_add(dir, name, &fhandle, &fattr);
  9549. +    iput(dir);
  9550. +    return error;
  9551. +}
  9552. +
  9553. +static int nfs_rmdir(struct inode *dir, const char *name, int len)
  9554. +{
  9555. +    int error;
  9556. +
  9557. +    if (!dir || !S_ISDIR(dir->i_mode)) {
  9558. +        printk("nfs_rmdir: inode is NULL or not a directory\n");
  9559. +        iput(dir);
  9560. +        return -ENOENT;
  9561. +    }
  9562. +    if (len > NFS_MAXNAMLEN) {
  9563. +        iput(dir);
  9564. +        return -ENAMETOOLONG;
  9565. +    }
  9566. +    error = nfs_proc_rmdir(NFS_SERVER(dir), NFS_FH(dir), name);
  9567. +    if (!error)
  9568. +        nfs_lookup_cache_remove(dir, NULL, name);
  9569. +    iput(dir);
  9570. +    return error;
  9571. +}
  9572. +
  9573. +static int nfs_unlink(struct inode *dir, const char *name, int len)
  9574. +{
  9575. +    int error;
  9576. +
  9577. +    if (!dir || !S_ISDIR(dir->i_mode)) {
  9578. +        printk("nfs_unlink: inode is NULL or not a directory\n");
  9579. +        iput(dir);
  9580. +        return -ENOENT;
  9581. +    }
  9582. +    if (len > NFS_MAXNAMLEN) {
  9583. +        iput(dir);
  9584. +        return -ENAMETOOLONG;
  9585. +    }
  9586. +    error = nfs_proc_remove(NFS_SERVER(dir), NFS_FH(dir), name);
  9587. +    if (!error)
  9588. +        nfs_lookup_cache_remove(dir, NULL, name);
  9589. +    iput(dir);
  9590. +    return error;
  9591. +}
  9592. +
  9593. +static int nfs_symlink(struct inode *dir, const char *name, int len,
  9594. +               const char *symname)
  9595. +{
  9596. +    struct nfs_sattr sattr;
  9597. +    int error;
  9598. +
  9599. +    if (!dir || !S_ISDIR(dir->i_mode)) {
  9600. +        printk("nfs_symlink: inode is NULL or not a directory\n");
  9601. +        iput(dir);
  9602. +        return -ENOENT;
  9603. +    }
  9604. +    if (len > NFS_MAXNAMLEN) {
  9605. +        iput(dir);
  9606. +        return -ENAMETOOLONG;
  9607. +    }
  9608. +    if (strlen(symname) > NFS_MAXPATHLEN) {
  9609. +        iput(dir);
  9610. +        return -ENAMETOOLONG;
  9611. +    }
  9612. +    sattr.mode = S_IFLNK | S_IRWXUGO; /* SunOS 4.1.2 crashes without this! */
  9613. +    sattr.uid = sattr.gid = sattr.size = (unsigned) -1;
  9614. +    sattr.atime.seconds = sattr.mtime.seconds = (unsigned) -1;
  9615. +    error = nfs_proc_symlink(NFS_SERVER(dir), NFS_FH(dir),
  9616. +        name, symname, &sattr);
  9617. +    iput(dir);
  9618. +    return error;
  9619. +}
  9620. +
  9621. +static int nfs_link(struct inode *oldinode, struct inode *dir,
  9622. +            const char *name, int len)
  9623. +{
  9624. +    int error;
  9625. +
  9626. +    if (!oldinode) {
  9627. +        printk("nfs_link: old inode is NULL\n");
  9628. +        iput(oldinode);
  9629. +        iput(dir);
  9630. +        return -ENOENT;
  9631. +    }
  9632. +    if (!dir || !S_ISDIR(dir->i_mode)) {
  9633. +        printk("nfs_link: dir is NULL or not a directory\n");
  9634. +        iput(oldinode);
  9635. +        iput(dir);
  9636. +        return -ENOENT;
  9637. +    }
  9638. +    if (len > NFS_MAXNAMLEN) {
  9639. +        iput(oldinode);
  9640. +        iput(dir);
  9641. +        return -ENAMETOOLONG;
  9642. +    }
  9643. +    error = nfs_proc_link(NFS_SERVER(oldinode), NFS_FH(oldinode),
  9644. +        NFS_FH(dir), name);
  9645. +    if (!error)
  9646. +        nfs_lookup_cache_remove(dir, oldinode, NULL);
  9647. +    iput(oldinode);
  9648. +    iput(dir);
  9649. +    return error;
  9650. +}
  9651. +
  9652. +static int nfs_rename(struct inode *old_dir, const char *old_name, int old_len,
  9653. +              struct inode *new_dir, const char *new_name, int new_len)
  9654. +{
  9655. +    int error;
  9656. +
  9657. +    if (!old_dir || !S_ISDIR(old_dir->i_mode)) {
  9658. +        printk("nfs_rename: old inode is NULL or not a directory\n");
  9659. +        iput(old_dir);
  9660. +        iput(new_dir);
  9661. +        return -ENOENT;
  9662. +    }
  9663. +    if (!new_dir || !S_ISDIR(new_dir->i_mode)) {
  9664. +        printk("nfs_rename: new inode is NULL or not a directory\n");
  9665. +        iput(old_dir);
  9666. +        iput(new_dir);
  9667. +        return -ENOENT;
  9668. +    }
  9669. +    if (old_len > NFS_MAXNAMLEN || new_len > NFS_MAXNAMLEN) {
  9670. +        iput(old_dir);
  9671. +        iput(new_dir);
  9672. +        return -ENAMETOOLONG;
  9673. +    }
  9674. +    error = nfs_proc_rename(NFS_SERVER(old_dir),
  9675. +        NFS_FH(old_dir), old_name,
  9676. +        NFS_FH(new_dir), new_name);
  9677. +    if (!error) {
  9678. +        nfs_lookup_cache_remove(old_dir, NULL, old_name);
  9679. +        nfs_lookup_cache_remove(new_dir, NULL, new_name);
  9680. +    }
  9681. +    iput(old_dir);
  9682. +    iput(new_dir);
  9683. +    return error;
  9684. +}
  9685. +
  9686. +/*
  9687. + * Many nfs protocol calls return the new file attributes after
  9688. + * an operation.  Here we update the inode to reflect the state
  9689. + * of the server's inode.
  9690. + */
  9691. +
  9692. +void nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
  9693. +{
  9694. +    int was_empty;
  9695. +
  9696. +    if (!inode || !fattr) {
  9697. +        printk("nfs_refresh_inode: inode or fattr is NULL\n");
  9698. +        return;
  9699. +    }
  9700. +    if (inode->i_ino != fattr->fileid) {
  9701. +        printk("nfs_refresh_inode: inode number mismatch\n");
  9702. +        return;
  9703. +    }
  9704. +    was_empty = inode->i_mode == 0;
  9705. +    inode->i_mode = fattr->mode;
  9706. +    inode->i_nlink = fattr->nlink;
  9707. +    inode->i_uid = fattr->uid;
  9708. +    inode->i_gid = fattr->gid;
  9709. +    inode->i_size = fattr->size;
  9710. +    inode->i_blksize = fattr->blocksize;
  9711. +    if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
  9712. +        inode->i_rdev = fattr->rdev;
  9713. +    else
  9714. +        inode->i_rdev = 0;
  9715. +    inode->i_blocks = fattr->blocks;
  9716. +    inode->i_atime = fattr->atime.seconds;
  9717. +    inode->i_mtime = fattr->mtime.seconds;
  9718. +    inode->i_ctime = fattr->ctime.seconds;
  9719. +    if (was_empty) {
  9720. +        if (S_ISREG(inode->i_mode))
  9721. +            inode->i_op = &nfs_file_inode_operations;
  9722. +        else if (S_ISDIR(inode->i_mode))
  9723. +            inode->i_op = &nfs_dir_inode_operations;
  9724. +        else if (S_ISLNK(inode->i_mode))
  9725. +            inode->i_op = &nfs_symlink_inode_operations;
  9726. +        else if (S_ISCHR(inode->i_mode))
  9727. +            inode->i_op = &chrdev_inode_operations;
  9728. +        else if (S_ISBLK(inode->i_mode))
  9729. +            inode->i_op = &blkdev_inode_operations;
  9730. +        else if (S_ISFIFO(inode->i_mode))
  9731. +            init_fifo(inode);
  9732. +        else
  9733. +            inode->i_op = NULL;
  9734. +    }
  9735. +    nfs_lookup_cache_refresh(inode, fattr);
  9736. +}
  9737. +
  9738. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/fs/nfs/file.c linux-0.9pl4/fs/nfs/file.c
  9739. --- linux-0.9pl3/fs/nfs/file.c    Wed Dec 31 19:00:00 1969
  9740. +++ linux-0.9pl4/fs/nfs/file.c    Wed Dec  1 07:44:15 1993
  9741. @@ -0,0 +1,163 @@
  9742. +/*
  9743. + *  linux/fs/nfs/file.c
  9744. + *
  9745. + *  Copyright (C) 1992  Rick Sladkey
  9746. + *
  9747. + *  nfs regular file handling functions
  9748. + */
  9749. +
  9750. +#include <asm/segment.h>
  9751. +#include <asm/system.h>
  9752. +
  9753. +#include <linux/sched.h>
  9754. +#include <linux/kernel.h>
  9755. +#include <linux/errno.h>
  9756. +#include <linux/fcntl.h>
  9757. +#include <linux/stat.h>
  9758. +#include <linux/mm.h>
  9759. +#include <linux/nfs_fs.h>
  9760. +#include <linux/malloc.h>
  9761. +
  9762. +static int nfs_file_read(struct inode *, struct file *, char *, int);
  9763. +static int nfs_file_write(struct inode *, struct file *, char *, int);
  9764. +static int nfs_fsync(struct inode *, struct file *);
  9765. +extern int nfs_mmap(struct inode * inode, struct file * file,
  9766. +          unsigned long addr, size_t len, int prot, unsigned long off);
  9767. +
  9768. +static struct file_operations nfs_file_operations = {
  9769. +    NULL,            /* lseek - default */
  9770. +    nfs_file_read,        /* read */
  9771. +    nfs_file_write,        /* write */
  9772. +    NULL,            /* readdir - bad */
  9773. +    NULL,            /* select - default */
  9774. +    NULL,            /* ioctl - default */
  9775. +    nfs_mmap,        /* mmap */
  9776. +    NULL,            /* no special open is needed */
  9777. +    NULL,            /* release */
  9778. +    nfs_fsync,        /* fsync */
  9779. +};
  9780. +
  9781. +struct inode_operations nfs_file_inode_operations = {
  9782. +    &nfs_file_operations,    /* default file operations */
  9783. +    NULL,            /* create */
  9784. +    NULL,            /* lookup */
  9785. +    NULL,            /* link */
  9786. +    NULL,            /* unlink */
  9787. +    NULL,            /* symlink */
  9788. +    NULL,            /* mkdir */
  9789. +    NULL,            /* rmdir */
  9790. +    NULL,            /* mknod */
  9791. +    NULL,            /* rename */
  9792. +    NULL,            /* readlink */
  9793. +    NULL,            /* follow_link */
  9794. +    NULL,            /* bmap */
  9795. +    NULL            /* truncate */
  9796. +};
  9797. +
  9798. +static int nfs_fsync(struct inode *inode, struct file *file)
  9799. +{
  9800. +    return 0;
  9801. +}
  9802. +
  9803. +static int nfs_file_read(struct inode *inode, struct file *file, char *buf,
  9804. +             int count)
  9805. +{
  9806. +    int result;
  9807. +    int hunk;
  9808. +    int i;
  9809. +    int n;
  9810. +    struct nfs_fattr fattr;
  9811. +    char *data;
  9812. +    off_t pos;
  9813. +
  9814. +    if (!inode) {
  9815. +        printk("nfs_file_read: inode = NULL\n");
  9816. +        return -EINVAL;
  9817. +    }
  9818. +    if (!S_ISREG(inode->i_mode)) {
  9819. +        printk("nfs_file_read: read from non-file, mode %07o\n",
  9820. +            inode->i_mode);
  9821. +        return -EINVAL;
  9822. +    }
  9823. +    pos = file->f_pos;
  9824. +    if (file->f_pos + count > inode->i_size)
  9825. +        count = inode->i_size - pos;
  9826. +    if (count <= 0)
  9827. +        return 0;
  9828. +    n = NFS_SERVER(inode)->rsize;
  9829. +    data = (char *) kmalloc(n, GFP_KERNEL);
  9830. +    for (i = 0; i < count; i += n) {
  9831. +        hunk = count - i;
  9832. +        if (hunk > n)
  9833. +            hunk = n;
  9834. +        result = nfs_proc_read(NFS_SERVER(inode), NFS_FH(inode), 
  9835. +            pos, hunk, data, &fattr);
  9836. +        if (result < 0) {
  9837. +            kfree_s(data, n);
  9838. +            return result;
  9839. +        }
  9840. +        memcpy_tofs(buf, data, result);
  9841. +        pos += result;
  9842. +        buf += result;
  9843. +        if (result < n) {
  9844. +            i += result;
  9845. +            break;
  9846. +        }
  9847. +    }
  9848. +    file->f_pos = pos;
  9849. +    kfree_s(data, n);
  9850. +    nfs_refresh_inode(inode, &fattr);
  9851. +    return i;
  9852. +}
  9853. +
  9854. +static int nfs_file_write(struct inode *inode, struct file *file, char *buf,
  9855. +              int count)
  9856. +{
  9857. +    int result;
  9858. +    int hunk;
  9859. +    int i;
  9860. +    int n;
  9861. +    struct nfs_fattr fattr;
  9862. +    char *data;
  9863. +    int pos;
  9864. +
  9865. +    if (!inode) {
  9866. +        printk("nfs_file_write: inode = NULL\n");
  9867. +        return -EINVAL;
  9868. +    }
  9869. +    if (!S_ISREG(inode->i_mode)) {
  9870. +        printk("nfs_file_write: write to non-file, mode %07o\n",
  9871. +            inode->i_mode);
  9872. +        return -EINVAL;
  9873. +    }
  9874. +    if (count <= 0)
  9875. +        return 0;
  9876. +    pos = file->f_pos;
  9877. +    if (file->f_flags & O_APPEND)
  9878. +        pos = inode->i_size;
  9879. +    n = NFS_SERVER(inode)->wsize;
  9880. +    data = (char *) kmalloc(n, GFP_KERNEL);
  9881. +    for (i = 0; i < count; i += n) {
  9882. +        hunk = count - i;
  9883. +        if (hunk >= n)
  9884. +            hunk = n;
  9885. +        memcpy_fromfs(data, buf, hunk);
  9886. +        result = nfs_proc_write(NFS_SERVER(inode), NFS_FH(inode), 
  9887. +            pos, hunk, data, &fattr);
  9888. +        if (result < 0) {
  9889. +            kfree_s(data, n);
  9890. +            return result;
  9891. +        }
  9892. +        pos += hunk;
  9893. +        buf += hunk;
  9894. +        if (hunk < n) {
  9895. +            i += hunk;
  9896. +            break;
  9897. +        }
  9898. +    }
  9899. +    file->f_pos = pos;
  9900. +    kfree_s(data, n);
  9901. +    nfs_refresh_inode(inode, &fattr);
  9902. +    return i;
  9903. +}
  9904. +
  9905. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/fs/nfs/inode.c linux-0.9pl4/fs/nfs/inode.c
  9906. --- linux-0.9pl3/fs/nfs/inode.c    Wed Dec 31 19:00:00 1969
  9907. +++ linux-0.9pl4/fs/nfs/inode.c    Wed Dec  1 07:44:15 1993
  9908. @@ -0,0 +1,233 @@
  9909. +/*
  9910. + *  linux/fs/nfs/inode.c
  9911. + *
  9912. + *  Copyright (C) 1992  Rick Sladkey
  9913. + *
  9914. + *  nfs inode and superblock handling functions
  9915. + */
  9916. +
  9917. +#include <asm/system.h>
  9918. +#include <asm/segment.h>
  9919. +
  9920. +#include <linux/sched.h>
  9921. +#include <linux/nfs_fs.h>
  9922. +#include <linux/kernel.h>
  9923. +#include <linux/mm.h>
  9924. +#include <linux/string.h>
  9925. +#include <linux/stat.h>
  9926. +#include <linux/errno.h>
  9927. +#include <linux/locks.h>
  9928. +
  9929. +extern int close_fp(struct file *filp, unsigned int fd);
  9930. +
  9931. +static int nfs_notify_change(int, struct inode *);
  9932. +static void nfs_put_inode(struct inode *);
  9933. +static void nfs_put_super(struct super_block *);
  9934. +static void nfs_statfs(struct super_block *, struct statfs *);
  9935. +
  9936. +static struct super_operations nfs_sops = { 
  9937. +    NULL,            /* read inode */
  9938. +    nfs_notify_change,    /* notify change */
  9939. +    NULL,            /* write inode */
  9940. +    nfs_put_inode,        /* put inode */
  9941. +    nfs_put_super,        /* put superblock */
  9942. +    NULL,            /* write superblock */
  9943. +    nfs_statfs,        /* stat filesystem */
  9944. +    NULL
  9945. +};
  9946. +
  9947. +static void nfs_put_inode(struct inode * inode)
  9948. +{
  9949. +    clear_inode(inode);
  9950. +}
  9951. +
  9952. +void nfs_put_super(struct super_block *sb)
  9953. +{
  9954. +        /* No locks should be open on this, so 0 should be safe as a fd. */
  9955. +    close_fp(sb->u.nfs_sb.s_server.file, 0);
  9956. +    lock_super(sb);
  9957. +    sb->s_dev = 0;
  9958. +    unlock_super(sb);
  9959. +}
  9960. +
  9961. +/*
  9962. + * The way this works is that the mount process passes a structure
  9963. + * in the data argument which contains an open socket to the NFS
  9964. + * server and the root file handle obtained from the server's mount
  9965. + * daemon.  We stash theses away in the private superblock fields.
  9966. + * Later we can add other mount parameters like caching values.
  9967. + */
  9968. +
  9969. +struct super_block *nfs_read_super(struct super_block *sb, void *raw_data,
  9970. +                   int silent)
  9971. +{
  9972. +    struct nfs_mount_data *data = (struct nfs_mount_data *) raw_data;
  9973. +    struct nfs_server *server;
  9974. +    unsigned int fd;
  9975. +    struct file *filp;
  9976. +    dev_t dev = sb->s_dev;
  9977. +
  9978. +    if (!data) {
  9979. +        printk("nfs_read_super: missing data argument\n");
  9980. +        sb->s_dev = 0;
  9981. +        return NULL;
  9982. +    }
  9983. +    fd = data->fd;
  9984. +    if (data->version != NFS_MOUNT_VERSION) {
  9985. +        printk("nfs warning: mount version %s than kernel\n",
  9986. +            data->version < NFS_MOUNT_VERSION ? "older" : "newer");
  9987. +    }
  9988. +    if (fd >= NR_OPEN || !(filp = current->filp[fd])) {
  9989. +        printk("nfs_read_super: invalid file descriptor\n");
  9990. +        sb->s_dev = 0;
  9991. +        return NULL;
  9992. +    }
  9993. +    if (!S_ISSOCK(filp->f_inode->i_mode)) {
  9994. +        printk("nfs_read_super: not a socket\n");
  9995. +        sb->s_dev = 0;
  9996. +        return NULL;
  9997. +    }
  9998. +    filp->f_count++;
  9999. +    lock_super(sb);
  10000. +    sb->s_blocksize = 1024; /* XXX */
  10001. +    sb->s_blocksize_bits = 10;
  10002. +    sb->s_magic = NFS_SUPER_MAGIC;
  10003. +    sb->s_dev = dev;
  10004. +    sb->s_op = &nfs_sops;
  10005. +    server = &sb->u.nfs_sb.s_server;
  10006. +    server->file = filp;
  10007. +    server->lock = 0;
  10008. +    server->wait = NULL;
  10009. +    server->flags = data->flags;
  10010. +    server->rsize = data->rsize;
  10011. +    if (server->rsize <= 0)
  10012. +        server->rsize = NFS_DEF_FILE_IO_BUFFER_SIZE;
  10013. +    else if (server->rsize >= NFS_MAX_FILE_IO_BUFFER_SIZE)
  10014. +        server->rsize = NFS_MAX_FILE_IO_BUFFER_SIZE;
  10015. +    server->wsize = data->wsize;
  10016. +    if (server->wsize <= 0)
  10017. +        server->wsize = NFS_DEF_FILE_IO_BUFFER_SIZE;
  10018. +    else if (server->wsize >= NFS_MAX_FILE_IO_BUFFER_SIZE)
  10019. +        server->wsize = NFS_MAX_FILE_IO_BUFFER_SIZE;
  10020. +    server->timeo = data->timeo*HZ/10;
  10021. +    server->retrans = data->retrans;
  10022. +    server->acregmin = data->acregmin*HZ;
  10023. +    server->acregmax = data->acregmax*HZ;
  10024. +    server->acdirmin = data->acdirmin*HZ;
  10025. +    server->acdirmax = data->acdirmax*HZ;
  10026. +    strcpy(server->hostname, data->hostname);
  10027. +    sb->u.nfs_sb.s_root = data->root;
  10028. +    unlock_super(sb);
  10029. +    if (!(sb->s_mounted = nfs_fhget(sb, &data->root, NULL))) {
  10030. +        sb->s_dev = 0;
  10031. +        printk("nfs_read_super: get root inode failed\n");
  10032. +        return NULL;
  10033. +    }
  10034. +    return sb;
  10035. +}
  10036. +
  10037. +void nfs_statfs(struct super_block *sb, struct statfs *buf)
  10038. +{
  10039. +    int error;
  10040. +    struct nfs_fsinfo res;
  10041. +
  10042. +    put_fs_long(NFS_SUPER_MAGIC, &buf->f_type);
  10043. +    error = nfs_proc_statfs(&sb->u.nfs_sb.s_server, &sb->u.nfs_sb.s_root,
  10044. +        &res);
  10045. +    if (error) {
  10046. +        printk("nfs_statfs: statfs error = %d\n", -error);
  10047. +        res.bsize = res.blocks = res.bfree = res.bavail = 0;
  10048. +    }
  10049. +    put_fs_long(res.bsize, &buf->f_bsize);
  10050. +    put_fs_long(res.blocks, &buf->f_blocks);
  10051. +    put_fs_long(res.bfree, &buf->f_bfree);
  10052. +    put_fs_long(res.bavail, &buf->f_bavail);
  10053. +    put_fs_long(0, &buf->f_files);
  10054. +    put_fs_long(0, &buf->f_ffree);
  10055. +    /* We should really try to interrogate the remote server to find
  10056. +       it's maximum name length here */
  10057. +    put_fs_long(NAME_MAX, &buf->f_namelen);
  10058. +}
  10059. +
  10060. +/*
  10061. + * This is our own version of iget that looks up inodes by file handle
  10062. + * instead of inode number.  We use this technique instead of using
  10063. + * the vfs read_inode function because there is no way to pass the
  10064. + * file handle or current attributes into the read_inode function.
  10065. + * We just have to be careful not to subvert iget's special handling
  10066. + * of mount points.
  10067. + */
  10068. +
  10069. +struct inode *nfs_fhget(struct super_block *sb, struct nfs_fh *fhandle,
  10070. +            struct nfs_fattr *fattr)
  10071. +{
  10072. +    struct nfs_fattr newfattr;
  10073. +    int error;
  10074. +    struct inode *inode;
  10075. +
  10076. +    if (!sb) {
  10077. +        printk("nfs_fhget: super block is NULL\n");
  10078. +        return NULL;
  10079. +    }
  10080. +    if (!fattr) {
  10081. +        error = nfs_proc_getattr(&sb->u.nfs_sb.s_server, fhandle,
  10082. +            &newfattr);
  10083. +        if (error) {
  10084. +            printk("nfs_fhget: getattr error = %d\n", -error);
  10085. +            return NULL;
  10086. +        }
  10087. +        fattr = &newfattr;
  10088. +    }
  10089. +    if (!(inode = iget(sb, fattr->fileid))) {
  10090. +        printk("nfs_fhget: iget failed\n");
  10091. +        return NULL;
  10092. +    }
  10093. +    if (inode->i_dev == sb->s_dev) {
  10094. +        if (inode->i_ino != fattr->fileid) {
  10095. +            printk("nfs_fhget: unexpected inode from iget\n");
  10096. +            return inode;
  10097. +        }
  10098. +        *NFS_FH(inode) = *fhandle;
  10099. +        nfs_refresh_inode(inode, fattr);
  10100. +    }
  10101. +    return inode;
  10102. +}
  10103. +
  10104. +int nfs_notify_change(int flags, struct inode *inode)
  10105. +{
  10106. +    struct nfs_sattr sattr;
  10107. +    struct nfs_fattr fattr;
  10108. +    int error;
  10109. +
  10110. +    if (flags & NOTIFY_MODE)
  10111. +        sattr.mode = inode->i_mode;
  10112. +    else
  10113. +        sattr.mode = (unsigned) -1;
  10114. +    if (flags & NOTIFY_UIDGID) {
  10115. +        sattr.uid = inode->i_uid;
  10116. +        sattr.gid = inode->i_gid;
  10117. +    }
  10118. +    else
  10119. +        sattr.uid = sattr.gid = (unsigned) -1;
  10120. +    if (flags & NOTIFY_SIZE)
  10121. +        sattr.size = S_ISREG(inode->i_mode) ? inode->i_size : -1;
  10122. +    else
  10123. +        sattr.size = (unsigned) -1;
  10124. +    if (flags & NOTIFY_TIME) {
  10125. +        sattr.mtime.seconds = inode->i_mtime;
  10126. +        sattr.mtime.useconds = 0;
  10127. +        sattr.atime.seconds = inode->i_atime;
  10128. +        sattr.atime.useconds = 0;
  10129. +    }
  10130. +    else {
  10131. +        sattr.mtime.seconds = sattr.mtime.useconds = (unsigned) -1;
  10132. +        sattr.atime.seconds = sattr.atime.useconds = (unsigned) -1;
  10133. +    }
  10134. +    error = nfs_proc_setattr(NFS_SERVER(inode), NFS_FH(inode),
  10135. +        &sattr, &fattr);
  10136. +    if (!error)
  10137. +        nfs_refresh_inode(inode, &fattr);
  10138. +    inode->i_dirt = 0;
  10139. +    return error;
  10140. +}
  10141. +
  10142. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/fs/nfs/mmap.c linux-0.9pl4/fs/nfs/mmap.c
  10143. --- linux-0.9pl3/fs/nfs/mmap.c    Wed Dec 31 19:00:00 1969
  10144. +++ linux-0.9pl4/fs/nfs/mmap.c    Mon Oct 10 16:48:26 1994
  10145. @@ -0,0 +1,161 @@
  10146. +/*
  10147. + *    fs/nfs/mmap.c    by Jon Tombs 15 Aug 1993
  10148. + *
  10149. + * This code is from
  10150. + *    linux/mm/mmap.c which was written by obz, Linus and Eric
  10151. + * and
  10152. + *    linux/mm/memory.c  by Linus Torvalds and others
  10153. + *
  10154. + *    Copyright (C) 1993
  10155. + *
  10156. + */
  10157. +#include <linux/stat.h>
  10158. +#include <linux/sched.h>
  10159. +#include <linux/kernel.h>
  10160. +#include <linux/mm.h>
  10161. +#include <linux/shm.h>
  10162. +#include <linux/errno.h>
  10163. +#include <linux/mman.h>
  10164. +#include <linux/string.h>
  10165. +#include <linux/malloc.h>
  10166. +#include <linux/nfs_fs.h>
  10167. +
  10168. +#include <asm/segment.h>
  10169. +#include <asm/system.h>
  10170. +
  10171. +extern int share_page(struct vm_area_struct * area, struct task_struct * tsk,
  10172. +    struct inode * inode, unsigned long address, unsigned long error_code,
  10173. +    unsigned long newpage);
  10174. +
  10175. +extern unsigned long put_page(struct task_struct * tsk,unsigned long page,
  10176. +    unsigned long address,int prot);
  10177. +
  10178. +static void nfs_file_mmap_nopage(int error_code, struct vm_area_struct * area,
  10179. +                unsigned long address);
  10180. +
  10181. +extern void file_mmap_free(struct vm_area_struct * area);
  10182. +extern int file_mmap_share(struct vm_area_struct * from, struct vm_area_struct * to,
  10183. +                unsigned long address);
  10184. +
  10185. +struct vm_operations_struct nfs_file_mmap = {
  10186. +    NULL,            /* open */
  10187. +    file_mmap_free,        /* close */
  10188. +    nfs_file_mmap_nopage,    /* nopage */
  10189. +    NULL,            /* wppage */
  10190. +    file_mmap_share,    /* share */
  10191. +    NULL,            /* unmap */
  10192. +};
  10193. +
  10194. +
  10195. +/* This is used for a general mmap of a nfs file */
  10196. +int nfs_mmap(struct inode * inode, struct file * file,
  10197. +    unsigned long addr, size_t len, int prot, unsigned long off)
  10198. +{
  10199. +    struct vm_area_struct * mpnt;
  10200. +
  10201. +    if (prot & PAGE_RW)    /* only PAGE_COW or read-only supported now */
  10202. +        return -EINVAL;
  10203. +    if (off & (inode->i_sb->s_blocksize - 1))
  10204. +        return -EINVAL;
  10205. +    if (!inode->i_sb || !S_ISREG(inode->i_mode))
  10206. +        return -EACCES;
  10207. +    if (!IS_RDONLY(inode)) {
  10208. +        inode->i_atime = CURRENT_TIME;
  10209. +        inode->i_dirt = 1;
  10210. +    }
  10211. +
  10212. +    mpnt = (struct vm_area_struct * ) kmalloc(sizeof(struct vm_area_struct), GFP_KERNEL);
  10213. +    if (!mpnt)
  10214. +        return -ENOMEM;
  10215. +
  10216. +    unmap_page_range(addr, len);
  10217. +    mpnt->vm_task = current;
  10218. +    mpnt->vm_start = addr;
  10219. +    mpnt->vm_end = addr + len;
  10220. +    mpnt->vm_page_prot = prot;
  10221. +    mpnt->vm_share = NULL;
  10222. +    mpnt->vm_inode = inode;
  10223. +    inode->i_count++;
  10224. +    mpnt->vm_offset = off;
  10225. +    mpnt->vm_ops = &nfs_file_mmap;
  10226. +    insert_vm_struct(current, mpnt);
  10227. +    merge_segments(current->mmap, NULL, NULL);
  10228. +    return 0;
  10229. +}
  10230. +
  10231. +
  10232. +static void nfs_file_mmap_nopage(int error_code, struct vm_area_struct * area,
  10233. +                unsigned long address)
  10234. +{
  10235. +    struct inode * inode = area->vm_inode;
  10236. +    unsigned int clear;
  10237. +    unsigned long page;
  10238. +    unsigned long tmp;
  10239. +    int n;
  10240. +    int i;
  10241. +    int pos;
  10242. +    struct nfs_fattr fattr;
  10243. +
  10244. +    address &= PAGE_MASK;
  10245. +    pos = address - area->vm_start + area->vm_offset;
  10246. +
  10247. +    page = get_free_page(GFP_KERNEL);
  10248. +    if (share_page(area, area->vm_task, inode, address, error_code, page)) {
  10249. +        ++area->vm_task->min_flt;
  10250. +        return;
  10251. +    }
  10252. +
  10253. +    ++area->vm_task->maj_flt;
  10254. +    if (!page) {
  10255. +        oom(current);
  10256. +        put_page(area->vm_task, BAD_PAGE, address, PAGE_PRIVATE);
  10257. +        return;
  10258. +    }
  10259. +
  10260. +    clear = 0;
  10261. +    if (address + PAGE_SIZE > area->vm_end) {
  10262. +        clear = address + PAGE_SIZE - area->vm_end;
  10263. +    }
  10264. +
  10265. +    n = NFS_SERVER(inode)->rsize; /* what we can read in one go */
  10266. +
  10267. +    for (i = 0; i < (PAGE_SIZE - clear); i += n) {
  10268. +        int hunk, result;
  10269. +
  10270. +        hunk = PAGE_SIZE - i;
  10271. +        if (hunk > n)
  10272. +            hunk = n;
  10273. +        result = nfs_proc_read(NFS_SERVER(inode), NFS_FH(inode),
  10274. +            pos, hunk, (char *) (page + i), &fattr);
  10275. +        if (result < 0)
  10276. +            break;
  10277. +        pos += result;
  10278. +        if (result < n) {
  10279. +            i += result;
  10280. +            break;
  10281. +        }
  10282. +    }
  10283. +
  10284. +#ifdef doweneedthishere
  10285. +    nfs_refresh_inode(inode, &fattr);
  10286. +#endif
  10287. +
  10288. +#if defined (__i386__)
  10289. +    if (!(error_code & PAGE_RW))
  10290. +#elif defined (__mc68000__)
  10291. +    if (!(error_code & 1))    /* ????? */
  10292. +#endif
  10293. +    {
  10294. +        if (share_page(area, area->vm_task, inode, address, error_code, page))
  10295. +            return;
  10296. +    }
  10297. +
  10298. +    tmp = page + PAGE_SIZE;
  10299. +    while (clear--) {
  10300. +        *(char *)--tmp = 0;
  10301. +    }
  10302. +    if (put_page(area->vm_task,page,address,area->vm_page_prot))
  10303. +        return;
  10304. +    free_page(page);
  10305. +    oom(current);
  10306. +}
  10307. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/fs/nfs/proc.c linux-0.9pl4/fs/nfs/proc.c
  10308. --- linux-0.9pl3/fs/nfs/proc.c    Wed Dec 31 19:00:00 1969
  10309. +++ linux-0.9pl4/fs/nfs/proc.c    Mon Feb 14 05:48:36 1994
  10310. @@ -0,0 +1,873 @@
  10311. +/*
  10312. + *  linux/fs/nfs/proc.c
  10313. + *
  10314. + *  Copyright (C) 1992, 1993, 1994  Rick Sladkey
  10315. + *
  10316. + *  OS-independent nfs remote procedure call functions
  10317. + */
  10318. +
  10319. +/*
  10320. + * Defining NFS_PROC_DEBUG causes a lookup of a file named
  10321. + * "xyzzy" to toggle debugging.  Just cd to an NFS-mounted
  10322. + * filesystem and type 'ls xyzzy' to turn on debugging.
  10323. + */
  10324. +
  10325. +#if 0
  10326. +#define NFS_PROC_DEBUG
  10327. +#endif
  10328. +
  10329. +#include <linux/config.h>
  10330. +#include <linux/param.h>
  10331. +#include <linux/sched.h>
  10332. +#include <linux/mm.h>
  10333. +#include <linux/nfs_fs.h>
  10334. +#include <linux/utsname.h>
  10335. +#include <linux/errno.h>
  10336. +#include <linux/string.h>
  10337. +#include <linux/in.h>
  10338. +
  10339. +#ifdef NFS_PROC_DEBUG
  10340. +
  10341. +static int proc_debug = 0;
  10342. +#define PRINTK(format, args...) \
  10343. +    do {                        \
  10344. +        if (proc_debug)                \
  10345. +            printk(format , ## args);    \
  10346. +    } while (0)
  10347. +
  10348. +#else /* !NFS_PROC_DEBUG */
  10349. +
  10350. +#define PRINTK(format, args...) do ; while (0)
  10351. +
  10352. +#endif /* !NFS_PROC_DEBUG */
  10353. +
  10354. +static int *nfs_rpc_header(int *p, int procedure, int ruid);
  10355. +static int *nfs_rpc_verify(int *p);
  10356. +static int nfs_stat_to_errno(int stat);
  10357. +
  10358. +/*
  10359. + * Our memory allocation and release functions.
  10360. + */
  10361. +
  10362. +static inline int *nfs_rpc_alloc(void)
  10363. +{
  10364. +    return (int *) __get_free_page(GFP_KERNEL);
  10365. +}
  10366. +
  10367. +static inline void nfs_rpc_free(int *p)
  10368. +{
  10369. +    free_page((long) p);
  10370. +}
  10371. +
  10372. +/*
  10373. + * Here are a bunch of xdr encode/decode functions that convert
  10374. + * between machine dependent and xdr data formats.
  10375. + */
  10376. +
  10377. +static inline int *xdr_encode_fhandle(int *p, struct nfs_fh *fhandle)
  10378. +{
  10379. +    *((struct nfs_fh *) p) = *fhandle;
  10380. +    p += (sizeof (*fhandle) + 3) >> 2;
  10381. +    return p;
  10382. +}
  10383. +
  10384. +static inline int *xdr_decode_fhandle(int *p, struct nfs_fh *fhandle)
  10385. +{
  10386. +    *fhandle = *((struct nfs_fh *) p);
  10387. +    p += (sizeof (*fhandle) + 3) >> 2;
  10388. +    return p;
  10389. +}
  10390. +
  10391. +static inline int *xdr_encode_string(int *p, const char *string)
  10392. +{
  10393. +    int len, quadlen;
  10394. +    
  10395. +    len = strlen(string);
  10396. +    quadlen = (len + 3) >> 2;
  10397. +    *p++ = htonl(len);
  10398. +    memcpy((char *) p, string, len);
  10399. +    memset(((char *) p) + len, '\0', (quadlen << 2) - len);
  10400. +    p += quadlen;
  10401. +    return p;
  10402. +}
  10403. +
  10404. +static inline int *xdr_decode_string(int *p, char *string, int maxlen)
  10405. +{
  10406. +    unsigned int len;
  10407. +
  10408. +    len = ntohl(*p++);
  10409. +    if (len > maxlen)
  10410. +        return NULL;
  10411. +    memcpy(string, (char *) p, len);
  10412. +    string[len] = '\0';
  10413. +    p += (len + 3) >> 2;
  10414. +    return p;
  10415. +}
  10416. +
  10417. +static inline int *xdr_encode_data(int *p, char *data, int len)
  10418. +{
  10419. +    int quadlen;
  10420. +    
  10421. +    quadlen = (len + 3) >> 2;
  10422. +    *p++ = htonl(len);
  10423. +    memcpy((char *) p, data, len);
  10424. +    memset(((char *) p) + len, '\0', (quadlen << 2) - len);
  10425. +    p += quadlen;
  10426. +    return p;
  10427. +}
  10428. +
  10429. +static inline int *xdr_decode_data(int *p, char *data, int *lenp, int maxlen)
  10430. +{
  10431. +    unsigned int len;
  10432. +
  10433. +    len = *lenp = ntohl(*p++);
  10434. +    if (len > maxlen)
  10435. +        return NULL;
  10436. +    memcpy(data, (char *) p, len);
  10437. +    p += (len + 3) >> 2;
  10438. +    return p;
  10439. +}
  10440. +
  10441. +static int *xdr_decode_fattr(int *p, struct nfs_fattr *fattr)
  10442. +{
  10443. +    fattr->type = (enum nfs_ftype) ntohl(*p++);
  10444. +    fattr->mode = ntohl(*p++);
  10445. +    fattr->nlink = ntohl(*p++);
  10446. +    fattr->uid = ntohl(*p++);
  10447. +    fattr->gid = ntohl(*p++);
  10448. +    fattr->size = ntohl(*p++);
  10449. +    fattr->blocksize = ntohl(*p++);
  10450. +    fattr->rdev = ntohl(*p++);
  10451. +    fattr->blocks = ntohl(*p++);
  10452. +    fattr->fsid = ntohl(*p++);
  10453. +    fattr->fileid = ntohl(*p++);
  10454. +    fattr->atime.seconds = ntohl(*p++);
  10455. +    fattr->atime.useconds = ntohl(*p++);
  10456. +    fattr->mtime.seconds = ntohl(*p++);
  10457. +    fattr->mtime.useconds = ntohl(*p++);
  10458. +    fattr->ctime.seconds = ntohl(*p++);
  10459. +    fattr->ctime.useconds = ntohl(*p++);
  10460. +    return p;
  10461. +}
  10462. +
  10463. +static int *xdr_encode_sattr(int *p, struct nfs_sattr *sattr)
  10464. +{
  10465. +    *p++ = htonl(sattr->mode);
  10466. +    *p++ = htonl(sattr->uid);
  10467. +    *p++ = htonl(sattr->gid);
  10468. +    *p++ = htonl(sattr->size);
  10469. +    *p++ = htonl(sattr->atime.seconds);
  10470. +    *p++ = htonl(sattr->atime.useconds);
  10471. +    *p++ = htonl(sattr->mtime.seconds);
  10472. +    *p++ = htonl(sattr->mtime.useconds);
  10473. +    return p;
  10474. +}
  10475. +
  10476. +static int *xdr_decode_entry(int *p, struct nfs_entry *entry)
  10477. +{
  10478. +    entry->fileid = ntohl(*p++);
  10479. +    if (!(p = xdr_decode_string(p, entry->name, NFS_MAXNAMLEN)))
  10480. +        return NULL;
  10481. +    entry->cookie = ntohl(*p++);
  10482. +    entry->eof = 0;
  10483. +    return p;
  10484. +}
  10485. +
  10486. +static int *xdr_decode_fsinfo(int *p, struct nfs_fsinfo *res)
  10487. +{
  10488. +    res->tsize = ntohl(*p++);
  10489. +    res->bsize = ntohl(*p++);
  10490. +    res->blocks = ntohl(*p++);
  10491. +    res->bfree = ntohl(*p++);
  10492. +    res->bavail = ntohl(*p++);
  10493. +    return p;
  10494. +}
  10495. +
  10496. +/*
  10497. + * One function for each procedure in the NFS protocol.
  10498. + */
  10499. +
  10500. +int nfs_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
  10501. +             struct nfs_fattr *fattr)
  10502. +{
  10503. +    int *p, *p0;
  10504. +    int status;
  10505. +    int ruid = 0;
  10506. +
  10507. +    PRINTK("NFS call  getattr\n");
  10508. +    if (!(p0 = nfs_rpc_alloc()))
  10509. +        return -EIO;
  10510. +retry:
  10511. +    p = nfs_rpc_header(p0, NFSPROC_GETATTR, ruid);
  10512. +    p = xdr_encode_fhandle(p, fhandle);
  10513. +    if ((status = nfs_rpc_call(server, p0, p)) < 0) {
  10514. +        nfs_rpc_free(p0);
  10515. +        return status;
  10516. +    }
  10517. +    if (!(p = nfs_rpc_verify(p0)))
  10518. +        status = NFSERR_IO;
  10519. +    else if ((status = ntohl(*p++)) == NFS_OK) {
  10520. +        p = xdr_decode_fattr(p, fattr);
  10521. +        PRINTK("NFS reply getattr\n");
  10522. +    }
  10523. +    else {
  10524. +        if (!ruid && current->euid == 0 && current->uid != 0) {
  10525. +            ruid = 1;
  10526. +            goto retry;
  10527. +        }
  10528. +        PRINTK("NFS reply getattr failed = %d\n", status);
  10529. +    }
  10530. +    nfs_rpc_free(p0);
  10531. +    return -nfs_stat_to_errno(status);
  10532. +}
  10533. +
  10534. +int nfs_proc_setattr(struct nfs_server *server, struct nfs_fh *fhandle,
  10535. +             struct nfs_sattr *sattr, struct nfs_fattr *fattr)
  10536. +{
  10537. +    int *p, *p0;
  10538. +    int status;
  10539. +    int ruid = 0;
  10540. +
  10541. +    PRINTK("NFS call  setattr\n");
  10542. +    if (!(p0 = nfs_rpc_alloc()))
  10543. +        return -EIO;
  10544. +retry:
  10545. +    p = nfs_rpc_header(p0, NFSPROC_SETATTR, ruid);
  10546. +    p = xdr_encode_fhandle(p, fhandle);
  10547. +    p = xdr_encode_sattr(p, sattr);
  10548. +    if ((status = nfs_rpc_call(server, p0, p)) < 0) {
  10549. +        nfs_rpc_free(p0);
  10550. +        return status;
  10551. +    }
  10552. +    if (!(p = nfs_rpc_verify(p0)))
  10553. +        status = NFSERR_IO;
  10554. +    else if ((status = ntohl(*p++)) == NFS_OK) {
  10555. +        p = xdr_decode_fattr(p, fattr);
  10556. +        PRINTK("NFS reply setattr\n");
  10557. +    }
  10558. +    else {
  10559. +        if (!ruid && current->euid == 0 && current->uid != 0) {
  10560. +            ruid = 1;
  10561. +            goto retry;
  10562. +        }
  10563. +        PRINTK("NFS reply setattr failed = %d\n", status);
  10564. +    }
  10565. +    nfs_rpc_free(p0);
  10566. +    return -nfs_stat_to_errno(status);
  10567. +}
  10568. +
  10569. +int nfs_proc_lookup(struct nfs_server *server, struct nfs_fh *dir, const char *name,
  10570. +            struct nfs_fh *fhandle, struct nfs_fattr *fattr)
  10571. +{
  10572. +    int *p, *p0;
  10573. +    int status;
  10574. +    int ruid = 0;
  10575. +
  10576. +    PRINTK("NFS call  lookup %s\n", name);
  10577. +#ifdef NFS_PROC_DEBUG
  10578. +    if (!strcmp(name, "xyzzy"))
  10579. +        proc_debug = 1 - proc_debug;
  10580. +#endif
  10581. +    if (!(p0 = nfs_rpc_alloc()))
  10582. +        return -EIO;
  10583. +retry:
  10584. +    p = nfs_rpc_header(p0, NFSPROC_LOOKUP, ruid);
  10585. +    p = xdr_encode_fhandle(p, dir);
  10586. +    p = xdr_encode_string(p, name);
  10587. +    if ((status = nfs_rpc_call(server, p0, p)) < 0) {
  10588. +        nfs_rpc_free(p0);
  10589. +        return status;
  10590. +    }
  10591. +    if (!(p = nfs_rpc_verify(p0)))
  10592. +        status = NFSERR_IO;
  10593. +    else if ((status = ntohl(*p++)) == NFS_OK) {
  10594. +        p = xdr_decode_fhandle(p, fhandle);
  10595. +        p = xdr_decode_fattr(p, fattr);
  10596. +        PRINTK("NFS reply lookup\n");
  10597. +    }
  10598. +    else {
  10599. +        if (!ruid && current->euid == 0 && current->uid != 0) {
  10600. +            ruid = 1;
  10601. +            goto retry;
  10602. +        }
  10603. +        PRINTK("NFS reply lookup failed = %d\n", status);
  10604. +    }
  10605. +    nfs_rpc_free(p0);
  10606. +    return -nfs_stat_to_errno(status);
  10607. +}
  10608. +
  10609. +int nfs_proc_readlink(struct nfs_server *server, struct nfs_fh *fhandle,
  10610. +              char *res)
  10611. +{
  10612. +    int *p, *p0;
  10613. +    int status;
  10614. +    int ruid = 0;
  10615. +
  10616. +    PRINTK("NFS call  readlink\n");
  10617. +    if (!(p0 = nfs_rpc_alloc()))
  10618. +        return -EIO;
  10619. +retry:
  10620. +    p = nfs_rpc_header(p0, NFSPROC_READLINK, ruid);
  10621. +    p = xdr_encode_fhandle(p, fhandle);
  10622. +    if ((status = nfs_rpc_call(server, p0, p)) < 0) {
  10623. +        nfs_rpc_free(p0);
  10624. +        return status;
  10625. +    }
  10626. +    if (!(p = nfs_rpc_verify(p0)))
  10627. +        status = NFSERR_IO;
  10628. +    else if ((status = ntohl(*p++)) == NFS_OK) {
  10629. +        if (!(p = xdr_decode_string(p, res, NFS_MAXPATHLEN))) {
  10630. +            printk("nfs_proc_readlink: giant pathname\n");
  10631. +            status = NFSERR_IO;
  10632. +        }
  10633. +        else
  10634. +            PRINTK("NFS reply readlink %s\n", res);
  10635. +    }
  10636. +    else {
  10637. +        if (!ruid && current->euid == 0 && current->uid != 0) {
  10638. +            ruid = 1;
  10639. +            goto retry;
  10640. +        }
  10641. +        PRINTK("NFS reply readlink failed = %d\n", status);
  10642. +    }
  10643. +    nfs_rpc_free(p0);
  10644. +    return -nfs_stat_to_errno(status);
  10645. +}
  10646. +
  10647. +int nfs_proc_read(struct nfs_server *server, struct nfs_fh *fhandle,
  10648. +          int offset, int count, char *data, struct nfs_fattr *fattr)
  10649. +{
  10650. +    int *p, *p0;
  10651. +    int status;
  10652. +    int ruid = 0;
  10653. +    int len = 0; /* = 0 is for gcc */
  10654. +
  10655. +    PRINTK("NFS call  read %d @ %d\n", count, offset);
  10656. +    if (!(p0 = nfs_rpc_alloc()))
  10657. +        return -EIO;
  10658. +retry:
  10659. +    p = nfs_rpc_header(p0, NFSPROC_READ, ruid);
  10660. +    p = xdr_encode_fhandle(p, fhandle);
  10661. +    *p++ = htonl(offset);
  10662. +    *p++ = htonl(count);
  10663. +    *p++ = htonl(count); /* traditional, could be any value */
  10664. +    if ((status = nfs_rpc_call(server, p0, p)) < 0) {
  10665. +        nfs_rpc_free(p0);
  10666. +        return status;
  10667. +    }
  10668. +    if (!(p = nfs_rpc_verify(p0)))
  10669. +        status = NFSERR_IO;
  10670. +    else if ((status = ntohl(*p++)) == NFS_OK) {
  10671. +        p = xdr_decode_fattr(p, fattr);
  10672. +        if (!(p = xdr_decode_data(p, data, &len, count))) {
  10673. +            printk("nfs_proc_read: giant data size\n"); 
  10674. +            status = NFSERR_IO;
  10675. +        }
  10676. +        else
  10677. +            PRINTK("NFS reply read %d\n", len);
  10678. +    }
  10679. +    else {
  10680. +        if (!ruid && current->euid == 0 && current->uid != 0) {
  10681. +            ruid = 1;
  10682. +            goto retry;
  10683. +        }
  10684. +        PRINTK("NFS reply read failed = %d\n", status);
  10685. +    }
  10686. +    nfs_rpc_free(p0);
  10687. +    return (status == NFS_OK) ? len : -nfs_stat_to_errno(status);
  10688. +}
  10689. +
  10690. +int nfs_proc_write(struct nfs_server *server, struct nfs_fh *fhandle,
  10691. +           int offset, int count, char *data, struct nfs_fattr *fattr)
  10692. +{
  10693. +    int *p, *p0;
  10694. +    int status;
  10695. +    int ruid = 0;
  10696. +
  10697. +    PRINTK("NFS call  write %d @ %d\n", count, offset);
  10698. +    if (!(p0 = nfs_rpc_alloc()))
  10699. +        return -EIO;
  10700. +retry:
  10701. +    p = nfs_rpc_header(p0, NFSPROC_WRITE, ruid);
  10702. +    p = xdr_encode_fhandle(p, fhandle);
  10703. +    *p++ = htonl(offset); /* traditional, could be any value */
  10704. +    *p++ = htonl(offset);
  10705. +    *p++ = htonl(count); /* traditional, could be any value */
  10706. +    p = xdr_encode_data(p, data, count);
  10707. +    if ((status = nfs_rpc_call(server, p0, p)) < 0) {
  10708. +        nfs_rpc_free(p0);
  10709. +        return status;
  10710. +    }
  10711. +    if (!(p = nfs_rpc_verify(p0)))
  10712. +        status = NFSERR_IO;
  10713. +    else if ((status = ntohl(*p++)) == NFS_OK) {
  10714. +        p = xdr_decode_fattr(p, fattr);
  10715. +        PRINTK("NFS reply write\n");
  10716. +    }
  10717. +    else {
  10718. +        if (!ruid && current->euid == 0 && current->uid != 0) {
  10719. +            ruid = 1;
  10720. +            goto retry;
  10721. +        }
  10722. +        PRINTK("NFS reply write failed = %d\n", status);
  10723. +    }
  10724. +    nfs_rpc_free(p0);
  10725. +    return -nfs_stat_to_errno(status);
  10726. +}
  10727. +
  10728. +int nfs_proc_create(struct nfs_server *server, struct nfs_fh *dir,
  10729. +            const char *name, struct nfs_sattr *sattr,
  10730. +            struct nfs_fh *fhandle, struct nfs_fattr *fattr)
  10731. +{
  10732. +    int *p, *p0;
  10733. +    int status;
  10734. +    int ruid = 0;
  10735. +
  10736. +    PRINTK("NFS call  create %s\n", name);
  10737. +    if (!(p0 = nfs_rpc_alloc()))
  10738. +        return -EIO;
  10739. +retry:
  10740. +    p = nfs_rpc_header(p0, NFSPROC_CREATE, ruid);
  10741. +    p = xdr_encode_fhandle(p, dir);
  10742. +    p = xdr_encode_string(p, name);
  10743. +    p = xdr_encode_sattr(p, sattr);
  10744. +    if ((status = nfs_rpc_call(server, p0, p)) < 0) {
  10745. +        nfs_rpc_free(p0);
  10746. +        return status;
  10747. +    }
  10748. +    if (!(p = nfs_rpc_verify(p0)))
  10749. +        status = NFSERR_IO;
  10750. +    else if ((status = ntohl(*p++)) == NFS_OK) {
  10751. +        p = xdr_decode_fhandle(p, fhandle);
  10752. +        p = xdr_decode_fattr(p, fattr);
  10753. +        PRINTK("NFS reply create\n");
  10754. +    }
  10755. +    else {
  10756. +        if (!ruid && current->euid == 0 && current->uid != 0) {
  10757. +            ruid = 1;
  10758. +            goto retry;
  10759. +        }
  10760. +        PRINTK("NFS reply create failed = %d\n", status);
  10761. +    }
  10762. +    nfs_rpc_free(p0);
  10763. +    return -nfs_stat_to_errno(status);
  10764. +}
  10765. +
  10766. +int nfs_proc_remove(struct nfs_server *server, struct nfs_fh *dir, const char *name)
  10767. +{
  10768. +    int *p, *p0;
  10769. +    int status;
  10770. +    int ruid = 0;
  10771. +
  10772. +    PRINTK("NFS call  remove %s\n", name);
  10773. +    if (!(p0 = nfs_rpc_alloc()))
  10774. +        return -EIO;
  10775. +retry:
  10776. +    p = nfs_rpc_header(p0, NFSPROC_REMOVE, ruid);
  10777. +    p = xdr_encode_fhandle(p, dir);
  10778. +    p = xdr_encode_string(p, name);
  10779. +    if ((status = nfs_rpc_call(server, p0, p)) < 0) {
  10780. +        nfs_rpc_free(p0);
  10781. +        return status;
  10782. +    }
  10783. +    if (!(p = nfs_rpc_verify(p0)))
  10784. +        status = NFSERR_IO;
  10785. +    else if ((status = ntohl(*p++)) == NFS_OK) {
  10786. +        PRINTK("NFS reply remove\n");
  10787. +    }
  10788. +    else {
  10789. +        if (!ruid && current->euid == 0 && current->uid != 0) {
  10790. +            ruid = 1;
  10791. +            goto retry;
  10792. +        }
  10793. +        PRINTK("NFS reply remove failed = %d\n", status);
  10794. +    }
  10795. +    nfs_rpc_free(p0);
  10796. +    return -nfs_stat_to_errno(status);
  10797. +}
  10798. +
  10799. +int nfs_proc_rename(struct nfs_server *server,
  10800. +            struct nfs_fh *old_dir, const char *old_name,
  10801. +            struct nfs_fh *new_dir, const char *new_name)
  10802. +{
  10803. +    int *p, *p0;
  10804. +    int status;
  10805. +    int ruid = 0;
  10806. +
  10807. +    PRINTK("NFS call  rename %s -> %s\n", old_name, new_name);
  10808. +    if (!(p0 = nfs_rpc_alloc()))
  10809. +        return -EIO;
  10810. +retry:
  10811. +    p = nfs_rpc_header(p0, NFSPROC_RENAME, ruid);
  10812. +    p = xdr_encode_fhandle(p, old_dir);
  10813. +    p = xdr_encode_string(p, old_name);
  10814. +    p = xdr_encode_fhandle(p, new_dir);
  10815. +    p = xdr_encode_string(p, new_name);
  10816. +    if ((status = nfs_rpc_call(server, p0, p)) < 0) {
  10817. +        nfs_rpc_free(p0);
  10818. +        return status;
  10819. +    }
  10820. +    if (!(p = nfs_rpc_verify(p0)))
  10821. +        status = NFSERR_IO;
  10822. +    else if ((status = ntohl(*p++)) == NFS_OK) {
  10823. +        PRINTK("NFS reply rename\n");
  10824. +    }
  10825. +    else {
  10826. +        if (!ruid && current->euid == 0 && current->uid != 0) {
  10827. +            ruid = 1;
  10828. +            goto retry;
  10829. +        }
  10830. +        PRINTK("NFS reply rename failed = %d\n", status);
  10831. +    }
  10832. +    nfs_rpc_free(p0);
  10833. +    return -nfs_stat_to_errno(status);
  10834. +}
  10835. +
  10836. +int nfs_proc_link(struct nfs_server *server, struct nfs_fh *fhandle,
  10837. +          struct nfs_fh *dir, const char *name)
  10838. +{
  10839. +    int *p, *p0;
  10840. +    int status;
  10841. +    int ruid = 0;
  10842. +
  10843. +    PRINTK("NFS call  link %s\n", name);
  10844. +    if (!(p0 = nfs_rpc_alloc()))
  10845. +        return -EIO;
  10846. +retry:
  10847. +    p = nfs_rpc_header(p0, NFSPROC_LINK, ruid);
  10848. +    p = xdr_encode_fhandle(p, fhandle);
  10849. +    p = xdr_encode_fhandle(p, dir);
  10850. +    p = xdr_encode_string(p, name);
  10851. +    if ((status = nfs_rpc_call(server, p0, p)) < 0) {
  10852. +        nfs_rpc_free(p0);
  10853. +        return status;
  10854. +    }
  10855. +    if (!(p = nfs_rpc_verify(p0)))
  10856. +        status = NFSERR_IO;
  10857. +    else if ((status = ntohl(*p++)) == NFS_OK) {
  10858. +        PRINTK("NFS reply link\n");
  10859. +    }
  10860. +    else {
  10861. +        if (!ruid && current->euid == 0 && current->uid != 0) {
  10862. +            ruid = 1;
  10863. +            goto retry;
  10864. +        }
  10865. +        PRINTK("NFS reply link failed = %d\n", status);
  10866. +    }
  10867. +    nfs_rpc_free(p0);
  10868. +    return -nfs_stat_to_errno(status);
  10869. +}
  10870. +
  10871. +int nfs_proc_symlink(struct nfs_server *server, struct nfs_fh *dir,
  10872. +             const char *name, const char *path, struct nfs_sattr *sattr)
  10873. +{
  10874. +    int *p, *p0;
  10875. +    int status;
  10876. +    int ruid = 0;
  10877. +
  10878. +    PRINTK("NFS call  symlink %s -> %s\n", name, path);
  10879. +    if (!(p0 = nfs_rpc_alloc()))
  10880. +        return -EIO;
  10881. +retry:
  10882. +    p = nfs_rpc_header(p0, NFSPROC_SYMLINK, ruid);
  10883. +    p = xdr_encode_fhandle(p, dir);
  10884. +    p = xdr_encode_string(p, name);
  10885. +    p = xdr_encode_string(p, path);
  10886. +    p = xdr_encode_sattr(p, sattr);
  10887. +    if ((status = nfs_rpc_call(server, p0, p)) < 0) {
  10888. +        nfs_rpc_free(p0);
  10889. +        return status;
  10890. +    }
  10891. +    if (!(p = nfs_rpc_verify(p0)))
  10892. +        status = NFSERR_IO;
  10893. +    else if ((status = ntohl(*p++)) == NFS_OK) {
  10894. +        PRINTK("NFS reply symlink\n");
  10895. +    }
  10896. +    else {
  10897. +        if (!ruid && current->euid == 0 && current->uid != 0) {
  10898. +            ruid = 1;
  10899. +            goto retry;
  10900. +        }
  10901. +        PRINTK("NFS reply symlink failed = %d\n", status);
  10902. +    }
  10903. +    nfs_rpc_free(p0);
  10904. +    return -nfs_stat_to_errno(status);
  10905. +}
  10906. +
  10907. +int nfs_proc_mkdir(struct nfs_server *server, struct nfs_fh *dir,
  10908. +           const char *name, struct nfs_sattr *sattr,
  10909. +           struct nfs_fh *fhandle, struct nfs_fattr *fattr)
  10910. +{
  10911. +    int *p, *p0;
  10912. +    int status;
  10913. +    int ruid = 0;
  10914. +
  10915. +    PRINTK("NFS call  mkdir %s\n", name);
  10916. +    if (!(p0 = nfs_rpc_alloc()))
  10917. +        return -EIO;
  10918. +retry:
  10919. +    p = nfs_rpc_header(p0, NFSPROC_MKDIR, ruid);
  10920. +    p = xdr_encode_fhandle(p, dir);
  10921. +    p = xdr_encode_string(p, name);
  10922. +    p = xdr_encode_sattr(p, sattr);
  10923. +    if ((status = nfs_rpc_call(server, p0, p)) < 0) {
  10924. +        nfs_rpc_free(p0);
  10925. +        return status;
  10926. +    }
  10927. +    if (!(p = nfs_rpc_verify(p0)))
  10928. +        status = NFSERR_IO;
  10929. +    else if ((status = ntohl(*p++)) == NFS_OK) {
  10930. +        p = xdr_decode_fhandle(p, fhandle);
  10931. +        p = xdr_decode_fattr(p, fattr);
  10932. +        PRINTK("NFS reply mkdir\n");
  10933. +    }
  10934. +    else {
  10935. +        if (!ruid && current->euid == 0 && current->uid != 0) {
  10936. +            ruid = 1;
  10937. +            goto retry;
  10938. +        }
  10939. +        PRINTK("NFS reply mkdir failed = %d\n", status);
  10940. +    }
  10941. +    nfs_rpc_free(p0);
  10942. +    return -nfs_stat_to_errno(status);
  10943. +}
  10944. +
  10945. +int nfs_proc_rmdir(struct nfs_server *server, struct nfs_fh *dir, const char *name)
  10946. +{
  10947. +    int *p, *p0;
  10948. +    int status;
  10949. +    int ruid = 0;
  10950. +
  10951. +    PRINTK("NFS call  rmdir %s\n", name);
  10952. +    if (!(p0 = nfs_rpc_alloc()))
  10953. +        return -EIO;
  10954. +retry:
  10955. +    p = nfs_rpc_header(p0, NFSPROC_RMDIR, ruid);
  10956. +    p = xdr_encode_fhandle(p, dir);
  10957. +    p = xdr_encode_string(p, name);
  10958. +    if ((status = nfs_rpc_call(server, p0, p)) < 0) {
  10959. +        nfs_rpc_free(p0);
  10960. +        return status;
  10961. +    }
  10962. +    if (!(p = nfs_rpc_verify(p0)))
  10963. +        status = NFSERR_IO;
  10964. +    else if ((status = ntohl(*p++)) == NFS_OK) {
  10965. +        PRINTK("NFS reply rmdir\n");
  10966. +    }
  10967. +    else {
  10968. +        if (!ruid && current->euid == 0 && current->uid != 0) {
  10969. +            ruid = 1;
  10970. +            goto retry;
  10971. +        }
  10972. +        PRINTK("NFS reply rmdir failed = %d\n", status);
  10973. +    }
  10974. +    nfs_rpc_free(p0);
  10975. +    return -nfs_stat_to_errno(status);
  10976. +}
  10977. +
  10978. +int nfs_proc_readdir(struct nfs_server *server, struct nfs_fh *fhandle,
  10979. +             int cookie, int count, struct nfs_entry *entry)
  10980. +{
  10981. +    int *p, *p0;
  10982. +    int status;
  10983. +    int ruid = 0;
  10984. +    int i = 0; /* = 0 is for gcc */
  10985. +    int size;
  10986. +    int eof;
  10987. +
  10988. +    PRINTK("NFS call  readdir %d @ %d\n", count, cookie);
  10989. +    size = server->rsize;
  10990. +    if (!(p0 = nfs_rpc_alloc()))
  10991. +        return -EIO;
  10992. +retry:
  10993. +    p = nfs_rpc_header(p0, NFSPROC_READDIR, ruid);
  10994. +    p = xdr_encode_fhandle(p, fhandle);
  10995. +    *p++ = htonl(cookie);
  10996. +    *p++ = htonl(size);
  10997. +    if ((status = nfs_rpc_call(server, p0, p)) < 0) {
  10998. +        nfs_rpc_free(p0);
  10999. +        return status;
  11000. +    }
  11001. +    if (!(p = nfs_rpc_verify(p0)))
  11002. +        status = NFSERR_IO;
  11003. +    else if ((status = ntohl(*p++)) == NFS_OK) {
  11004. +        for (i = 0; i < count && *p++; i++) {
  11005. +            if (!(p = xdr_decode_entry(p, entry++)))
  11006. +                break;
  11007. +        }
  11008. +        if (!p) {
  11009. +            printk("nfs_proc_readdir: giant filename\n");
  11010. +            status = NFSERR_IO;
  11011. +        }
  11012. +        else {
  11013. +            eof = (i == count && !*p++ && *p++)
  11014. +                  || (i < count && *p++);
  11015. +            if (eof && i)
  11016. +                entry[-1].eof = 1;
  11017. +            PRINTK("NFS reply readdir %d %s\n", i,
  11018. +                   eof ? "eof" : "");
  11019. +        }
  11020. +    }
  11021. +    else {
  11022. +        if (!ruid && current->euid == 0 && current->uid != 0) {
  11023. +            ruid = 1;
  11024. +            goto retry;
  11025. +        }
  11026. +        PRINTK("NFS reply readdir failed = %d\n", status);
  11027. +    }
  11028. +    nfs_rpc_free(p0);
  11029. +    return (status == NFS_OK) ? i : -nfs_stat_to_errno(status);
  11030. +}
  11031. +
  11032. +int nfs_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle,
  11033. +            struct nfs_fsinfo *res)
  11034. +{
  11035. +    int *p, *p0;
  11036. +    int status;
  11037. +    int ruid = 0;
  11038. +
  11039. +    PRINTK("NFS call  statfs\n");
  11040. +    if (!(p0 = nfs_rpc_alloc()))
  11041. +        return -EIO;
  11042. +retry:
  11043. +    p = nfs_rpc_header(p0, NFSPROC_STATFS, ruid);
  11044. +    p = xdr_encode_fhandle(p, fhandle);
  11045. +    if ((status = nfs_rpc_call(server, p0, p)) < 0) {
  11046. +        nfs_rpc_free(p0);
  11047. +        return status;
  11048. +    }
  11049. +    if (!(p = nfs_rpc_verify(p0)))
  11050. +        status = NFSERR_IO;
  11051. +    else if ((status = ntohl(*p++)) == NFS_OK) {
  11052. +        p = xdr_decode_fsinfo(p, res);
  11053. +        PRINTK("NFS reply statfs\n");
  11054. +    }
  11055. +    else {
  11056. +        if (!ruid && current->euid == 0 && current->uid != 0) {
  11057. +            ruid = 1;
  11058. +            goto retry;
  11059. +        }
  11060. +        PRINTK("NFS reply statfs failed = %d\n", status);
  11061. +    }
  11062. +    nfs_rpc_free(p0);
  11063. +    return -nfs_stat_to_errno(status);
  11064. +}
  11065. +
  11066. +/*
  11067. + * Here are a few RPC-assist functions.
  11068. + */
  11069. +
  11070. +static int *nfs_rpc_header(int *p, int procedure, int ruid)
  11071. +{
  11072. +    int *p1, *p2;
  11073. +    int i;
  11074. +    static int xid = 0;
  11075. +    unsigned char *sys = (unsigned char *) system_utsname.nodename;
  11076. +
  11077. +    if (xid == 0) {
  11078. +        xid = CURRENT_TIME;
  11079. +        xid ^= (sys[3]<<24) | (sys[2]<<16) | (sys[1]<<8) | sys[0];
  11080. +    }
  11081. +    *p++ = htonl(++xid);
  11082. +    *p++ = htonl(RPC_CALL);
  11083. +    *p++ = htonl(RPC_VERSION);
  11084. +    *p++ = htonl(NFS_PROGRAM);
  11085. +    *p++ = htonl(NFS_VERSION);
  11086. +    *p++ = htonl(procedure);
  11087. +    *p++ = htonl(RPC_AUTH_UNIX);
  11088. +    p1 = p++;
  11089. +    *p++ = htonl(CURRENT_TIME); /* traditional, could be anything */
  11090. +    p = xdr_encode_string(p, (char *) sys);
  11091. +    *p++ = htonl(ruid ? current->uid : current->euid);
  11092. +    *p++ = htonl(current->egid);
  11093. +    p2 = p++;
  11094. +    for (i = 0; i < 16 && i < NGROUPS && current->groups[i] != NOGROUP; i++)
  11095. +        *p++ = htonl(current->groups[i]);
  11096. +    *p2 = htonl(i);
  11097. +    *p1 = htonl((p - (p1 + 1)) << 2);
  11098. +    *p++ = htonl(RPC_AUTH_NULL);
  11099. +    *p++ = htonl(0);
  11100. +    return p;
  11101. +}
  11102. +
  11103. +static int *nfs_rpc_verify(int *p)
  11104. +{
  11105. +    unsigned int n;
  11106. +
  11107. +    p++;
  11108. +    if ((n = ntohl(*p++)) != RPC_REPLY) {
  11109. +        printk("nfs_rpc_verify: not an RPC reply: %d\n", n);
  11110. +        return NULL;
  11111. +    }
  11112. +    if ((n = ntohl(*p++)) != RPC_MSG_ACCEPTED) {
  11113. +        printk("nfs_rpc_verify: RPC call rejected: %d\n", n);
  11114. +        return NULL;
  11115. +    }
  11116. +    switch (n = ntohl(*p++)) {
  11117. +    case RPC_AUTH_NULL: case RPC_AUTH_UNIX: case RPC_AUTH_SHORT:
  11118. +        break;
  11119. +    default:
  11120. +        printk("nfs_rpc_verify: bad RPC authentication type: %d\n", n);
  11121. +        return NULL;
  11122. +    }
  11123. +    if ((n = ntohl(*p++)) > 400) {
  11124. +        printk("nfs_rpc_verify: giant auth size\n");
  11125. +        return NULL;
  11126. +    }
  11127. +    p += (n + 3) >> 2;
  11128. +    if ((n = ntohl(*p++)) != RPC_SUCCESS) {
  11129. +        printk("nfs_rpc_verify: RPC call failed: %d\n", n);
  11130. +        return NULL;
  11131. +    }
  11132. +    return p;
  11133. +}
  11134. +    
  11135. +/*
  11136. + * We need to translate between nfs status return values and
  11137. + * the local errno values which may not be the same.
  11138. + */
  11139. +
  11140. +#ifndef EDQUOT
  11141. +#define EDQUOT    ENOSPC
  11142. +#endif
  11143. +
  11144. +static struct {
  11145. +    int stat;
  11146. +    int errno;
  11147. +} nfs_errtbl[] = {
  11148. +    { NFS_OK,        0        },
  11149. +    { NFSERR_PERM,        EPERM        },
  11150. +    { NFSERR_NOENT,        ENOENT        },
  11151. +    { NFSERR_IO,        EIO        },
  11152. +    { NFSERR_NXIO,        ENXIO        },
  11153. +    { NFSERR_ACCES,        EACCES        },
  11154. +    { NFSERR_EXIST,        EEXIST        },
  11155. +    { NFSERR_NODEV,        ENODEV        },
  11156. +    { NFSERR_NOTDIR,    ENOTDIR        },
  11157. +    { NFSERR_ISDIR,        EISDIR        },
  11158. +    { NFSERR_INVAL,        EINVAL        },
  11159. +    { NFSERR_FBIG,        EFBIG        },
  11160. +    { NFSERR_NOSPC,        ENOSPC        },
  11161. +    { NFSERR_ROFS,        EROFS        },
  11162. +    { NFSERR_NAMETOOLONG,    ENAMETOOLONG    },
  11163. +    { NFSERR_NOTEMPTY,    ENOTEMPTY    },
  11164. +    { NFSERR_DQUOT,        EDQUOT        },
  11165. +    { NFSERR_STALE,        ESTALE        },
  11166. +#ifdef EWFLUSH
  11167. +    { NFSERR_WFLUSH,    EWFLUSH        },
  11168. +#endif
  11169. +    { -1,            EIO        }
  11170. +};
  11171. +
  11172. +static int nfs_stat_to_errno(int stat)
  11173. +{
  11174. +    int i;
  11175. +
  11176. +    for (i = 0; nfs_errtbl[i].stat != -1; i++) {
  11177. +        if (nfs_errtbl[i].stat == stat)
  11178. +            return nfs_errtbl[i].errno;
  11179. +    }
  11180. +    printk("nfs_stat_to_errno: bad nfs status return value: %d\n", stat);
  11181. +    return nfs_errtbl[i].errno;
  11182. +}
  11183. +
  11184. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/fs/nfs/sock.c linux-0.9pl4/fs/nfs/sock.c
  11185. --- linux-0.9pl3/fs/nfs/sock.c    Wed Dec 31 19:00:00 1969
  11186. +++ linux-0.9pl4/fs/nfs/sock.c    Tue Mar  1 01:03:41 1994
  11187. @@ -0,0 +1,185 @@
  11188. +/*
  11189. + *  linux/fs/nfs/sock.c
  11190. + *
  11191. + *  Copyright (C) 1992, 1993  Rick Sladkey
  11192. + *
  11193. + *  low-level nfs remote procedure call interface
  11194. + */
  11195. +
  11196. +#include <linux/config.h>
  11197. +#include <linux/sched.h>
  11198. +#include <linux/nfs_fs.h>
  11199. +#include <linux/errno.h>
  11200. +#include <linux/socket.h>
  11201. +#include <linux/fcntl.h>
  11202. +#include <asm/segment.h>
  11203. +#include <linux/in.h>
  11204. +#include <linux/net.h>
  11205. +
  11206. +
  11207. +extern struct socket *socki_lookup(struct inode *inode);
  11208. +
  11209. +#define _S(nr) (1<<((nr)-1))
  11210. +
  11211. +/*
  11212. + * We violate some modularity principles here by poking around
  11213. + * in some socket internals.  Besides having to call socket
  11214. + * functions from kernel-space instead of user space, the socket
  11215. + * interface does not lend itself well to being cleanly called
  11216. + * without a file descriptor.  Since the nfs calls can run on
  11217. + * behalf of any process, the superblock maintains a file pointer
  11218. + * to the server socket.
  11219. + */
  11220. +
  11221. +static int do_nfs_rpc_call(struct nfs_server *server, int *start, int *end)
  11222. +{
  11223. +    struct file *file;
  11224. +    struct inode *inode;
  11225. +    struct socket *sock;
  11226. +    unsigned short fs;
  11227. +    int result;
  11228. +    int xid;
  11229. +    int len;
  11230. +    select_table wait_table;
  11231. +    struct select_table_entry entry;
  11232. +    int (*select) (struct inode *, struct file *, int, select_table *);
  11233. +    int init_timeout, max_timeout;
  11234. +    int timeout;
  11235. +    int retrans;
  11236. +    int major_timeout_seen;
  11237. +    char *server_name;
  11238. +    int n;
  11239. +    int addrlen;
  11240. +    unsigned long old_mask;
  11241. +
  11242. +    xid = start[0];
  11243. +    len = ((char *) end) - ((char *) start);
  11244. +    file = server->file;
  11245. +    inode = file->f_inode;
  11246. +    select = file->f_op->select;
  11247. +    sock = socki_lookup(inode);
  11248. +    if (!sock) {
  11249. +        printk("nfs_rpc_call: socki_lookup failed\n");
  11250. +        return -EBADF;
  11251. +    }
  11252. +    init_timeout = server->timeo;
  11253. +    max_timeout = NFS_MAX_RPC_TIMEOUT*HZ/10;
  11254. +    retrans = server->retrans;
  11255. +    major_timeout_seen = 0;
  11256. +    server_name = server->hostname;
  11257. +    old_mask = current->blocked;
  11258. +    current->blocked |= ~(_S(SIGKILL)
  11259. +#if 0
  11260. +        | _S(SIGSTOP)
  11261. +#endif
  11262. +        | ((server->flags & NFS_MOUNT_INTR)
  11263. +        ? ((current->sigaction[SIGINT - 1].sa_handler == SIG_DFL
  11264. +            ? _S(SIGINT) : 0)
  11265. +        | (current->sigaction[SIGQUIT - 1].sa_handler == SIG_DFL
  11266. +            ? _S(SIGQUIT) : 0))
  11267. +        : 0));
  11268. +    fs = get_fs();
  11269. +    set_fs(get_ds());
  11270. +    for (n = 0, timeout = init_timeout; ; n++, timeout <<= 1) {
  11271. +        result = sock->ops->send(sock, (void *) start, len, 0, 0);
  11272. +        if (result < 0) {
  11273. +            printk("nfs_rpc_call: send error = %d\n", result);
  11274. +            break;
  11275. +        }
  11276. +    re_select:
  11277. +        wait_table.nr = 0;
  11278. +        wait_table.entry = &entry;
  11279. +        current->state = TASK_INTERRUPTIBLE;
  11280. +        if (!select(inode, file, SEL_IN, &wait_table)
  11281. +            && !select(inode, file, SEL_IN, NULL)) {
  11282. +            if (timeout > max_timeout)
  11283. +                timeout = max_timeout;
  11284. +            current->timeout = jiffies + timeout;
  11285. +            schedule();
  11286. +            remove_wait_queue(entry.wait_address, &entry.wait);
  11287. +            current->state = TASK_RUNNING;
  11288. +            if (current->signal & ~current->blocked) {
  11289. +                current->timeout = 0;
  11290. +                result = -ERESTARTSYS;
  11291. +                break;
  11292. +            }
  11293. +            if (!current->timeout) {
  11294. +                if (n < retrans)
  11295. +                    continue;
  11296. +                if (server->flags & NFS_MOUNT_SOFT) {
  11297. +                    printk("NFS server %s not responding, "
  11298. +                        "timed out\n", server_name);
  11299. +                    result = -EIO;
  11300. +                    break;
  11301. +                }
  11302. +                n = 0;
  11303. +                timeout = init_timeout;
  11304. +                init_timeout <<= 1;
  11305. +                if (!major_timeout_seen) {
  11306. +                    printk("NFS server %s not responding, "
  11307. +                        "still trying\n", server_name);
  11308. +                }
  11309. +                major_timeout_seen = 1;
  11310. +                continue;
  11311. +            }
  11312. +            else
  11313. +                current->timeout = 0;
  11314. +        }
  11315. +        else if (wait_table.nr)
  11316. +            remove_wait_queue(entry.wait_address, &entry.wait);
  11317. +        current->state = TASK_RUNNING;
  11318. +        addrlen = 0;
  11319. +        result = sock->ops->recvfrom(sock, (void *) start, PAGE_SIZE, 1, 0,
  11320. +            NULL, &addrlen);
  11321. +        if (result < 0) {
  11322. +            if (result == -EAGAIN) {
  11323. +#if 0
  11324. +                printk("nfs_rpc_call: bad select ready\n");
  11325. +#endif
  11326. +                goto re_select;
  11327. +            }
  11328. +            if (result == -ECONNREFUSED) {
  11329. +#if 0
  11330. +                printk("nfs_rpc_call: server playing coy\n");
  11331. +#endif
  11332. +                goto re_select;
  11333. +            }
  11334. +            if (result != -ERESTARTSYS) {
  11335. +                printk("nfs_rpc_call: recv error = %d\n",
  11336. +                    -result);
  11337. +            }
  11338. +            break;
  11339. +        }
  11340. +        if (*start == xid) {
  11341. +            if (major_timeout_seen)
  11342. +                printk("NFS server %s OK\n", server_name);
  11343. +            break;
  11344. +        }
  11345. +#if 0
  11346. +        printk("nfs_rpc_call: XID mismatch\n");
  11347. +#endif
  11348. +    }
  11349. +    current->blocked = old_mask;
  11350. +    set_fs(fs);
  11351. +    return result;
  11352. +}
  11353. +
  11354. +/*
  11355. + * For now we lock out other simulaneous nfs calls for the same filesytem
  11356. + * because we are single-threaded and don't want to get mismatched
  11357. + * RPC replies.
  11358. + */
  11359. +
  11360. +int nfs_rpc_call(struct nfs_server *server, int *start, int *end)
  11361. +{
  11362. +    int result;
  11363. +
  11364. +    while (server->lock)
  11365. +        sleep_on(&server->wait);
  11366. +    server->lock = 1;
  11367. +    result = do_nfs_rpc_call(server, start, end);
  11368. +    server->lock = 0;
  11369. +    wake_up(&server->wait);
  11370. +    return result;
  11371. +}
  11372. +
  11373. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/fs/nfs/symlink.c linux-0.9pl4/fs/nfs/symlink.c
  11374. --- linux-0.9pl3/fs/nfs/symlink.c    Wed Dec 31 19:00:00 1969
  11375. +++ linux-0.9pl4/fs/nfs/symlink.c    Wed Dec  1 07:44:15 1993
  11376. @@ -0,0 +1,108 @@
  11377. +/*
  11378. + *  linux/fs/nfs/symlink.c
  11379. + *
  11380. + *  Copyright (C) 1992  Rick Sladkey
  11381. + *
  11382. + *  nfs symlink handling code
  11383. + */
  11384. +
  11385. +#include <asm/segment.h>
  11386. +
  11387. +#include <linux/sched.h>
  11388. +#include <linux/errno.h>
  11389. +#include <linux/nfs_fs.h>
  11390. +#include <linux/stat.h>
  11391. +#include <linux/mm.h>
  11392. +#include <linux/malloc.h>
  11393. +
  11394. +static int nfs_readlink(struct inode *, char *, int);
  11395. +static int nfs_follow_link(struct inode *, struct inode *, int, int,
  11396. +               struct inode **);
  11397. +
  11398. +/*
  11399. + * symlinks can't do much...
  11400. + */
  11401. +struct inode_operations nfs_symlink_inode_operations = {
  11402. +    NULL,            /* no file-operations */
  11403. +    NULL,            /* create */
  11404. +    NULL,            /* lookup */
  11405. +    NULL,            /* link */
  11406. +    NULL,            /* unlink */
  11407. +    NULL,            /* symlink */
  11408. +    NULL,            /* mkdir */
  11409. +    NULL,            /* rmdir */
  11410. +    NULL,            /* mknod */
  11411. +    NULL,            /* rename */
  11412. +    nfs_readlink,        /* readlink */
  11413. +    nfs_follow_link,    /* follow_link */
  11414. +    NULL,            /* bmap */
  11415. +    NULL,            /* truncate */
  11416. +    NULL            /* permission */
  11417. +};
  11418. +
  11419. +static int nfs_follow_link(struct inode *dir, struct inode *inode,
  11420. +               int flag, int mode, struct inode **res_inode)
  11421. +{
  11422. +    int error;
  11423. +    char *res;
  11424. +
  11425. +    *res_inode = NULL;
  11426. +    if (!dir) {
  11427. +        dir = current->root;
  11428. +        dir->i_count++;
  11429. +    }
  11430. +    if (!inode) {
  11431. +        iput(dir);
  11432. +        return -ENOENT;
  11433. +    }
  11434. +    if (!S_ISLNK(inode->i_mode)) {
  11435. +        iput(dir);
  11436. +        *res_inode = inode;
  11437. +        return 0;
  11438. +    }
  11439. +    if (current->link_count > 5) {
  11440. +        iput(inode);
  11441. +        iput(dir);
  11442. +        return -ELOOP;
  11443. +    }
  11444. +    res = (char *) kmalloc(NFS_MAXPATHLEN + 1, GFP_KERNEL);
  11445. +    error = nfs_proc_readlink(NFS_SERVER(inode), NFS_FH(inode), res);
  11446. +    if (error) {
  11447. +        iput(inode);
  11448. +        iput(dir);
  11449. +        kfree_s(res, NFS_MAXPATHLEN + 1);
  11450. +        return error;
  11451. +    }
  11452. +    iput(inode);
  11453. +    current->link_count++;
  11454. +    error = open_namei(res, flag, mode, res_inode, dir);
  11455. +    current->link_count--;
  11456. +    kfree_s(res, NFS_MAXPATHLEN + 1);
  11457. +    return error;
  11458. +}
  11459. +
  11460. +static int nfs_readlink(struct inode *inode, char *buffer, int buflen)
  11461. +{
  11462. +    int i;
  11463. +    char c;
  11464. +    int error;
  11465. +    char *res;
  11466. +
  11467. +    if (!S_ISLNK(inode->i_mode)) {
  11468. +        iput(inode);
  11469. +        return -EINVAL;
  11470. +    }
  11471. +    if (buflen > NFS_MAXPATHLEN)
  11472. +        buflen = NFS_MAXPATHLEN;
  11473. +    res = (char *) kmalloc(buflen + 1, GFP_KERNEL);
  11474. +    error = nfs_proc_readlink(NFS_SERVER(inode), NFS_FH(inode), res);
  11475. +    iput(inode);
  11476. +    if (error) {
  11477. +        kfree_s(res, buflen + 1);
  11478. +        return error;
  11479. +    }
  11480. +    for (i = 0; i < buflen && (c = res[i]); i++)
  11481. +        put_fs_byte(c,buffer++);
  11482. +    kfree_s(res, buflen + 1);
  11483. +    return i;
  11484. +}
  11485. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/include/asm/segment.h linux-0.9pl4/include/asm/segment.h
  11486. --- linux-0.9pl3/include/asm/segment.h    Fri Aug 19 17:05:08 1994
  11487. +++ linux-0.9pl4/include/asm/segment.h    Mon Oct 10 16:48:26 1994
  11488. @@ -83,20 +83,19 @@
  11489.  
  11490.  static inline void __constant_memcpy_tofs(void * to, const void * from, unsigned long n)
  11491.  {
  11492. -    switch (n) {
  11493. -        case 0:
  11494. +    if (n == 0) {
  11495.              return;
  11496. -        case 1:
  11497. +    } else if (n == 1) {
  11498.              put_user_byte(*(const char *) from, (char *) to);
  11499.              return;
  11500. -        case 2:
  11501. +    } else if (n == 2) {
  11502.              put_user_word(*(const short *) from, (short *) to);
  11503.              return;
  11504. -        case 3:
  11505. +    } else if (n == 3) {
  11506.              put_user_word(*(const short *) from, (short *) to);
  11507.              put_user_byte(*(2+(const char *) from), 2+(char *) to);
  11508.              return;
  11509. -        case 4:
  11510. +    } else if (n == 4) {
  11511.              put_user_long(*(const int *) from, (int *) to);
  11512.              return;
  11513.      }
  11514. @@ -150,20 +149,19 @@
  11515.  
  11516.  static inline void __constant_memcpy_fromfs(void * to, const void * from, unsigned long n)
  11517.  {
  11518. -    switch (n) {
  11519. -        case 0:
  11520. +    if (n == 0) {
  11521.              return;
  11522. -        case 1:
  11523. +    } else if (n == 1) {
  11524.              *(char *)to = get_user_byte((const char *) from);
  11525.              return;
  11526. -        case 2:
  11527. +    } else if (n == 2) {
  11528.              *(short *)to = get_user_word((const short *) from);
  11529.              return;
  11530. -        case 3:
  11531. +    } else if (n == 3) {
  11532.              *(short *) to = get_user_word((const short *) from);
  11533.              *(2+(char *) to) = get_user_byte(2+(const char *) from);
  11534.              return;
  11535. -        case 4:
  11536. +    } else if (n == 4) {
  11537.              *(int *) to = get_user_long((const int *) from);
  11538.              return;
  11539.      }
  11540. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/include/linux/amihdreg.h linux-0.9pl4/include/linux/amihdreg.h
  11541. --- linux-0.9pl3/include/linux/amihdreg.h    Sun Aug 14 10:29:35 1994
  11542. +++ linux-0.9pl4/include/linux/amihdreg.h    Thu Nov 24 20:52:38 1994
  11543. @@ -10,20 +10,23 @@
  11544.  #define IDE_DISABLE_IRQ  0x02
  11545.  #define IDE_ENABLE_IRQ   0x00
  11546.   
  11547. -/* Hd controller regs. Ref: Disassembling scsi.device */
  11548. -#define HD_DATA        0xdd2020    /* _CTL when writing */
  11549. -#define HD_ERROR    0xdd2026    /* see err-bits */
  11550. -#define HD_NSECTOR    0xdd202a    /* nr of sectors to read/write */
  11551. -#define HD_SECTOR    0xdd202e    /* starting sector */
  11552. -#define HD_LCYL        0xdd2032    /* starting cylinder */
  11553. -#define HD_HCYL        0xdd2036    /* high byte of starting cyl */
  11554. -#define HD_CURRENT    0xdd203a    /* 101dhhhh , d=drive, hhhh=head */
  11555. -#define HD_STATUS    0xdd203e    /* see status-bits */
  11556. -#define HD_PRECOMP HD_ERROR    /* same io address, read=error, write=precomp */
  11557. -#define HD_COMMAND HD_STATUS    /* same io address, read=status, write=cmd */
  11558. +/* Bases of the hard drive controller */
  11559. +#define HD_BASE_A4000   0xdd2020
  11560. +#define HD_BASE_A1200   0xda0000
  11561.  
  11562. -#define HD_IRQ_TEST 0xdd3020  /* MSB = 1, Harddisk is source of interrupt */
  11563. -#define HD_CMD          0xdd303a
  11564. +/* Offsets from one of the above bases */
  11565. +#define HD_ERROR    (0x06)        /* see err-bits */
  11566. +#define HD_NSECTOR    (0x0a)        /* nr of sectors to read/write */
  11567. +#define HD_SECTOR    (0x0e)        /* starting sector */
  11568. +#define HD_LCYL        (0x12)        /* starting cylinder */
  11569. +#define HD_HCYL        (0x16)        /* high byte of starting cyl */
  11570. +#define HD_CURRENT    (0x1a)        /* 101dhhhh , d=drive, hhhh=head */
  11571. +#define HD_STATUS    (0x1e)        /* see status-bits */
  11572. +#define HD_CMD        (0x101a)
  11573. +
  11574. +/* These are at different offsets from the base */
  11575. +#define HD_A4000_IRQ    (0xdd3020)    /* MSB = 1, Harddisk is source of interrupt */
  11576. +#define HD_A1200_IRQ    (0xda9000)    /* MSB = 1, Harddisk is source of interrupt */
  11577.  
  11578.  /* Bits of HD_STATUS */
  11579.  #define ERR_STAT    0x01
  11580. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/include/linux/atafdreg.h linux-0.9pl4/include/linux/atafdreg.h
  11581. --- linux-0.9pl3/include/linux/atafdreg.h    Sun Aug 14 10:29:37 1994
  11582. +++ linux-0.9pl4/include/linux/atafdreg.h    Mon Nov  7 22:33:51 1994
  11583. @@ -5,10 +5,22 @@
  11584.  ** WD1772 stuff
  11585.   */
  11586.  
  11587. -#define FDCSELREG_STP   (0x80)
  11588. -#define FDCSELREG_TRA   (0x82)
  11589. -#define FDCSELREG_SEC   (0x84)
  11590. -#define FDCSELREG_DTA   (0x86)
  11591. +/* register codes */
  11592. +
  11593. +#define FDCSELREG_STP   (0x80)   /* command/status register */
  11594. +#define FDCSELREG_TRA   (0x82)   /* track register */
  11595. +#define FDCSELREG_SEC   (0x84)   /* sector register */
  11596. +#define FDCSELREG_DTA   (0x86)   /* data register */
  11597. +
  11598. +/* register names for FDC_READ/WRITE macros */
  11599. +
  11600. +#define FDCREG_CMD        0
  11601. +#define FDCREG_STATUS    0
  11602. +#define FDCREG_TRACK    2
  11603. +#define FDCREG_SECTOR    4
  11604. +#define FDCREG_DATA        6
  11605. +
  11606. +/* command opcodes */
  11607.  
  11608.  #define FDCCMD_RESTORE  (0x00)   /*  -                   */
  11609.  #define FDCCMD_SEEK     (0x10)   /*   |                  */
  11610. @@ -20,26 +32,35 @@
  11611.  #define FDCCMD_RDADR    (0xc0)   /*  -                   */
  11612.  #define FDCCMD_RDTRA    (0xe0)   /*   |  TYP 3 Commands  */
  11613.  #define FDCCMD_WRTRA    (0xf0)   /*  -                   */
  11614. -#define FDCCMD_FORCI    (0xc0)   /*  -   TYP 4 Command   */
  11615. +#define FDCCMD_FORCI    (0xd0)   /*  -   TYP 4 Command   */
  11616. +
  11617. +/* command modifier bits */
  11618.  
  11619. -#define FDCCMDADD_SR6   (0x00)
  11620. +#define FDCCMDADD_SR6   (0x00)   /* step rate settings */
  11621.  #define FDCCMDADD_SR12  (0x01)
  11622.  #define FDCCMDADD_SR2   (0x02)
  11623.  #define FDCCMDADD_SR3   (0x03)
  11624. -
  11625. -#define FDCCMDADD_V     (0x04)
  11626. -
  11627. -#define FDCCMDADD_H     (0x08)
  11628. -
  11629. -#define FDCCMDADD_U     (0x10)
  11630. -
  11631. -#define FDCCMDADD_M     (0x10)
  11632. -
  11633. -#define FDCCMDADD_E     (0x04)
  11634. -
  11635. -#define FDCCMDADD_P     (0x02)
  11636. -
  11637. -#define FDCCMDADD_A0    (0x01)
  11638. +#define FDCCMDADD_V     (0x04)   /* verify */
  11639. +#define FDCCMDADD_H     (0x08)   /* wait for spin-up */
  11640. +#define FDCCMDADD_U     (0x10)   /* update track register */
  11641. +#define FDCCMDADD_M     (0x10)   /* multiple sector access */
  11642. +#define FDCCMDADD_E     (0x04)   /* head settling flag */
  11643. +#define FDCCMDADD_P     (0x02)   /* precompensation */
  11644. +#define FDCCMDADD_A0    (0x01)   /* DAM flag */
  11645. +
  11646. +/* status register bits */
  11647. +
  11648. +#define    FDCSTAT_MOTORON    (0x80)   /* motor on */
  11649. +#define    FDCSTAT_WPROT    (0x40)   /* write protected (FDCCMD_WR*) */
  11650. +#define    FDCSTAT_SPINUP    (0x20)   /* motor speed stable (Type I) */
  11651. +#define    FDCSTAT_DELDAM    (0x20)   /* sector has deleted DAM (Type II+III) */
  11652. +#define    FDCSTAT_RECNF    (0x10)   /* record not found */
  11653. +#define    FDCSTAT_CRC        (0x08)   /* CRC error */
  11654. +#define    FDCSTAT_TR00    (0x04)   /* Track 00 flag (Type I) */
  11655. +#define    FDCSTAT_LOST    (0x04)   /* Lost Data (Type II+III) */
  11656. +#define    FDCSTAT_IDX        (0x02)   /* Index status (Type I) */
  11657. +#define    FDCSTAT_DRQ        (0x02)   /* DRQ status (Type II+III) */
  11658. +#define    FDCSTAT_BUSY    (0x01)   /* FDC is busy */
  11659.  
  11660.  
  11661.  /* PSG Port A Bit Nr 0 .. Side Sel .. 0 -> Side 1  1 -> Side 2 */
  11662. @@ -47,25 +68,12 @@
  11663.          
  11664.  #define DSKDRVNONE  (0x06)
  11665.  #define DSKDRV0     (0x02)
  11666. -#define DSKDRV1     (0x02)
  11667. -
  11668. +#define DSKDRV1     (0x04)
  11669.  
  11670. -/*
  11671. -** Misc
  11672. -*/
  11673. -#define MFM_SYNC    0x4489          /* standard MFM sync value */
  11674. -
  11675. -/* Values for FD_COMMAND */
  11676. -#define FD_RECALIBRATE        0x07    /* move to track 0 */
  11677. -#define FD_SEEK            0x0F    /* seek track */
  11678. -#define FD_READ            0xE6    /* read with MT, MFM, SKip deleted */
  11679. -#define FD_WRITE        0xC5    /* write with MT, MFM */
  11680. -#define FD_SENSEI        0x08    /* Sense Interrupt Status */
  11681. -#define FD_SPECIFY        0x03    /* specify HUT etc */
  11682. -#define FD_FORMAT        0x4D    /* format one track */
  11683. -#define FD_VERSION        0x10    /* get version code */
  11684. -#define FD_CONFIGURE        0x13    /* configure FIFO operation */
  11685. -#define FD_PERPENDICULAR    0x12    /* perpendicular r/w mode */
  11686. +/* step rates */
  11687. +#define    FDCSTEP_6    0x00
  11688. +#define    FDCSTEP_12    0x01
  11689. +#define    FDCSTEP_2    0x02
  11690. +#define    FDCSTEP_3    0x03
  11691.  
  11692.  #endif
  11693. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/include/linux/atari_stdma.h linux-0.9pl4/include/linux/atari_stdma.h
  11694. --- linux-0.9pl3/include/linux/atari_stdma.h    Sun Aug 14 10:29:37 1994
  11695. +++ linux-0.9pl4/include/linux/atari_stdma.h    Mon Nov  7 22:33:52 1994
  11696. @@ -11,6 +11,8 @@
  11697.  void stdma_lock( isrfunc isr, void *data );
  11698.  void stdma_release( void );
  11699.  int stdma_others_waiting( void );
  11700. +int stdma_islocked( void );
  11701. +void *stdma_locked_by( void );
  11702.  void stdma_init( void );
  11703.  
  11704.  /************************* End of Prototypes **************************/
  11705. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/include/linux/atarihw.h linux-0.9pl4/include/linux/atarihw.h
  11706. --- linux-0.9pl3/include/linux/atarihw.h    Sun Aug 14 10:29:37 1994
  11707. +++ linux-0.9pl4/include/linux/atarihw.h    Mon Nov  7 22:33:52 1994
  11708. @@ -20,7 +20,11 @@
  11709.  
  11710.  /* Memory used for screen ram and stdma buffers */
  11711.  void atari_stram_init (void);
  11712. +#if 0
  11713.  void *atari_stram_alloc (long size);
  11714. +#else
  11715. +void *atari_stram_alloc (long size, unsigned long *start_mem );
  11716. +#endif
  11717.  void atari_stram_free (void *);
  11718.  
  11719.  /* 
  11720. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/include/linux/bootinfo.h linux-0.9pl4/include/linux/bootinfo.h
  11721. --- linux-0.9pl3/include/linux/bootinfo.h    Sun Aug 14 10:29:16 1994
  11722. +++ linux-0.9pl4/include/linux/bootinfo.h    Mon Nov  7 22:34:38 1994
  11723. @@ -62,8 +62,6 @@
  11724.  
  11725.  struct bi_Atari {
  11726.      AtariModel    model;
  11727. -    unsigned long stram_start;    /* Start of unmapped ST-RAM */
  11728. -    unsigned long stram_size;    /* Size of unmapped ST-RAM */
  11729.  };
  11730.  
  11731.  /*
  11732. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/include/linux/config.h linux-0.9pl4/include/linux/config.h
  11733. --- linux-0.9pl3/include/linux/config.h    Sun Aug 14 10:29:15 1994
  11734. +++ linux-0.9pl4/include/linux/config.h    Mon Oct 10 16:48:27 1994
  11735. @@ -15,7 +15,7 @@
  11736.   * Defines for what uname() should return
  11737.   */
  11738.  #ifndef UTS_SYSNAME
  11739. -#define UTS_SYSNAME "Linux/68k"
  11740. +#define UTS_SYSNAME "Linux"
  11741.  #endif
  11742.  
  11743.  #ifndef UTS_NODENAME
  11744. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/include/linux/console.h linux-0.9pl4/include/linux/console.h
  11745. --- linux-0.9pl3/include/linux/console.h    Sun Aug 14 10:29:14 1994
  11746. +++ linux-0.9pl4/include/linux/console.h    Mon Oct 24 22:27:10 1994
  11747. @@ -25,11 +25,14 @@
  11748.      unsigned char    vc_s_color;        /* Saved foreground & background */
  11749.      unsigned char    vc_ulcolor;        /* Colour for underline mode */
  11750.      unsigned char    vc_halfcolor;        /* Colour for half intensity mode */
  11751. +    unsigned short    *vc_pos;
  11752.      unsigned long    vc_x,vc_y;
  11753.      unsigned long    vc_top,vc_bottom;
  11754.      unsigned long    vc_rows,vc_cols;
  11755. +    unsigned long    vc_size_row;
  11756.      unsigned long    vc_state;
  11757.      unsigned long    vc_npar,vc_par[NPAR];
  11758. +    unsigned short    *vc_video_mem_start;
  11759.      unsigned long    vc_saved_x;
  11760.      unsigned long    vc_saved_y;
  11761.      /* mode flags */
  11762. @@ -52,6 +55,7 @@
  11763.      /* misc */
  11764.      unsigned long    vc_ques        : 1;
  11765.      unsigned long    vc_need_wrap    : 1;
  11766. +    unsigned long    vc_can_do_color    : 1;
  11767.      unsigned long    vc_tab_stop[5];        /* Tab stops. 160 columns. */
  11768.      unsigned char * vc_translate;
  11769.      unsigned char *    vc_G0_charset;
  11770. @@ -71,11 +75,11 @@
  11771.  /* DPC: 1994-04-13 !!! con_putcs is new entry !!! */
  11772.  
  11773.  struct consw {
  11774. -    long   (*con_init)(struct condata *, long);
  11775. +    long   (*con_init)(struct condata *, long, char **);
  11776.      int    (*con_deinit)(struct condata *);
  11777.      int    (*con_clear)(struct condata *, int, int, int, int);
  11778. -    int    (*con_putc)(struct condata *, int, int, int, int);
  11779. -    int    (*con_putcs)(struct condata *, const char *, int, int, int, int);
  11780. +    int    (*con_putc)(struct condata *, int, int, int);
  11781. +    int    (*con_putcs)(struct condata *, const char *, int, int, int);
  11782.      int    (*con_cursor)(struct condata *, int);
  11783.      int    (*con_scroll)(struct condata *, int, int, int, int);
  11784.      int    (*con_bmove)(struct condata *, int, int, int, int, int, int);
  11785. @@ -88,12 +92,6 @@
  11786.  
  11787.  /* flag bits */
  11788.  #define CON_INITED  (1)
  11789. -
  11790. -/* definitions for draw mode */
  11791. -#define DM_CLEAR    (1)
  11792. -#define DM_COPY     (2)
  11793. -#define DM_XOR      (3)
  11794. -#define DM_INVERSE  (4)
  11795.  
  11796.  /* scroll */
  11797.  #define SM_UP       (1)
  11798. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/include/linux/kd.h linux-0.9pl4/include/linux/kd.h
  11799. --- linux-0.9pl3/include/linux/kd.h    Sun Aug 14 10:29:15 1994
  11800. +++ linux-0.9pl4/include/linux/kd.h    Mon Nov  7 22:36:01 1994
  11801. @@ -212,4 +212,5 @@
  11802.  /* note: 0x4B60 and 0x4B61 used above for GIO_FONT and PIO_FONT
  11803.           0x4B62 and 0x4B63 used above for KDGKBMETA and KDSKBMETA */
  11804.  
  11805. +#define GET_SCRADDR    0x4b70    /* get the start of screen mem */
  11806.  #endif /* _LINUX_KD_H */
  11807. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/include/linux/keyboard.h linux-0.9pl4/include/linux/keyboard.h
  11808. --- linux-0.9pl3/include/linux/keyboard.h    Sun Aug 14 10:29:33 1994
  11809. +++ linux-0.9pl4/include/linux/keyboard.h    Thu Nov 24 21:21:52 1994
  11810. @@ -18,14 +18,18 @@
  11811.  
  11812.  #define NR_KEYS 128
  11813.  #define NR_KEYMAPS 16
  11814. +#ifdef __KERNEL__
  11815.  extern const int NR_TYPES;
  11816.  extern const int max_vals[];
  11817.  extern unsigned short (*key_map)[NR_KEYS];
  11818. +#endif
  11819.  
  11820.  #define NR_FUNC 36
  11821.  #define FUNC_BUFSIZE 512
  11822. +#ifdef __KERNEL__
  11823.  extern char func_buf[FUNC_BUFSIZE];
  11824.  extern char *func_table[NR_FUNC];
  11825. +#endif
  11826.  
  11827.  #define KT_LATIN    0    /* we depend on this being zero */
  11828.  #define KT_LETTER      11    /* symbol that can be acted upon by CapsLock */
  11829. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/include/linux/major.h linux-0.9pl4/include/linux/major.h
  11830. --- linux-0.9pl3/include/linux/major.h    Sun Aug 14 10:29:14 1994
  11831. +++ linux-0.9pl4/include/linux/major.h    Mon Nov  7 22:36:52 1994
  11832. @@ -45,6 +45,7 @@
  11833.   * 25 -                        matsushita cdrom       minors 0..3
  11834.   * 26 -
  11835.   * 27 - qic117 tape
  11836. + * 28 -                   acsi disk
  11837.   */
  11838.  
  11839.  #define UNNAMED_MAJOR    0
  11840. @@ -73,6 +74,7 @@
  11841.  #define CDU535_CDROM_MAJOR 24
  11842.  #define MATSUSHITA_CDROM_MAJOR 25
  11843.  #define QIC117_TAPE_MAJOR 27
  11844. +#define ACSI_MAJOR    28
  11845.  
  11846.  /*
  11847.   * Tests for SCSI devices.
  11848. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/include/linux/mm.h linux-0.9pl4/include/linux/mm.h
  11849. --- linux-0.9pl3/include/linux/mm.h    Sun Aug 28 17:16:17 1994
  11850. +++ linux-0.9pl4/include/linux/mm.h    Mon Nov 21 18:34:17 1994
  11851. @@ -19,6 +19,7 @@
  11852.  #include <linux/sched.h>
  11853.  #include <linux/errno.h>
  11854.  #include <linux/kernel.h>
  11855. +#include <asm/segment.h>
  11856.  
  11857.  #define VERIFY_READ 0
  11858.  #define VERIFY_WRITE 1
  11859. @@ -33,10 +34,12 @@
  11860.      if (size > TASK_SIZE - (unsigned long) addr)
  11861.          return -EFAULT;
  11862.  #elif defined(__mc68000__)
  11863. -    if (current->pid != 1 && TASK_SIZE <= (unsigned long) addr)
  11864. +    if (current->pid != 1 && get_fs () != get_ds ()) {
  11865. +        if (TASK_SIZE <= (unsigned long) addr)
  11866.          return -EFAULT;
  11867. -    if (current->pid != 1 && size > TASK_SIZE - (unsigned long) addr)
  11868. +        if (size > TASK_SIZE - (unsigned long) addr)
  11869.          return -EFAULT;
  11870. +    }
  11871.  #endif
  11872.      if (wp_works_ok || type == VERIFY_READ || !size)
  11873.          return 0;
  11874. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/include/linux/nfs_fs.h linux-0.9pl4/include/linux/nfs_fs.h
  11875. --- linux-0.9pl3/include/linux/nfs_fs.h    Wed Dec 31 19:00:00 1969
  11876. +++ linux-0.9pl4/include/linux/nfs_fs.h    Wed Dec  1 07:44:15 1993
  11877. @@ -0,0 +1,124 @@
  11878. +#ifndef _LINUX_NFS_FS_H
  11879. +#define _LINUX_NFS_FS_H
  11880. +
  11881. +/*
  11882. + *  linux/include/linux/nfs_fs.h
  11883. + *
  11884. + *  Copyright (C) 1992  Rick Sladkey
  11885. + *
  11886. + *  OS-specific nfs filesystem definitions and declarations
  11887. + */
  11888. +
  11889. +#include <linux/nfs.h>
  11890. +
  11891. +#include <linux/in.h>
  11892. +#include <linux/nfs_mount.h>
  11893. +
  11894. +/*
  11895. + * The readdir cache size controls how many directory entries are cached.
  11896. + * Its size is limited by the number of nfs_entry structures that can fit
  11897. + * in one 4096-byte page, currently 256.
  11898. + */
  11899. +
  11900. +#define NFS_READDIR_CACHE_SIZE        64
  11901. +
  11902. +/*
  11903. + * WARNING!  The I/O buffer size cannot be bigger than about 3900 for now.
  11904. + * It needs to fit inside a 4096-byte page and leave room for the RPC and
  11905. + * NFS headers.  But it ought to at least be a multiple of 512 and probably
  11906. + * should be a power of 2.  I don't think Linux TCP/IP can handle more than
  11907. + * about 1800 yet.
  11908. + */
  11909. +
  11910. +#define NFS_MAX_FILE_IO_BUFFER_SIZE    (7*512)
  11911. +#define NFS_DEF_FILE_IO_BUFFER_SIZE    1024
  11912. +
  11913. +/*
  11914. + * The upper limit on timeouts for the exponential backoff algorithm
  11915. + * in tenths of a second.
  11916. + */
  11917. +
  11918. +#define NFS_MAX_RPC_TIMEOUT        600
  11919. +
  11920. +/*
  11921. + * Size of the lookup cache in units of number of entries cached.
  11922. + * It is better not to make this too large although the optimimum
  11923. + * depends on a usage and environment.
  11924. + */
  11925. +
  11926. +#define NFS_LOOKUP_CACHE_SIZE        64
  11927. +
  11928. +#define NFS_SUPER_MAGIC            0x6969
  11929. +
  11930. +#define NFS_SERVER(inode)        (&(inode)->i_sb->u.nfs_sb.s_server)
  11931. +#define NFS_FH(inode)            (&(inode)->u.nfs_i.fhandle)
  11932. +
  11933. +/* linux/fs/nfs/proc.c */
  11934. +
  11935. +extern int nfs_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
  11936. +                struct nfs_fattr *fattr);
  11937. +extern int nfs_proc_setattr(struct nfs_server *server, struct nfs_fh *fhandle,
  11938. +                struct nfs_sattr *sattr, struct nfs_fattr *fattr);
  11939. +extern int nfs_proc_lookup(struct nfs_server *server, struct nfs_fh *dir,
  11940. +               const char *name, struct nfs_fh *fhandle,
  11941. +               struct nfs_fattr *fattr);
  11942. +extern int nfs_proc_readlink(struct nfs_server *server, struct nfs_fh *fhandle,
  11943. +                 char *res);
  11944. +extern int nfs_proc_read(struct nfs_server *server, struct nfs_fh *fhandle,
  11945. +             int offset, int count, char *data,
  11946. +             struct nfs_fattr *fattr);
  11947. +extern int nfs_proc_write(struct nfs_server *server, struct nfs_fh *fhandle,
  11948. +              int offset, int count, char *data,
  11949. +              struct nfs_fattr *fattr);
  11950. +extern int nfs_proc_create(struct nfs_server *server, struct nfs_fh *dir,
  11951. +               const char *name, struct nfs_sattr *sattr,
  11952. +               struct nfs_fh *fhandle, struct nfs_fattr *fattr);
  11953. +extern int nfs_proc_remove(struct nfs_server *server, struct nfs_fh *dir,
  11954. +               const char *name);
  11955. +extern int nfs_proc_rename(struct nfs_server *server,
  11956. +               struct nfs_fh *old_dir, const char *old_name,
  11957. +               struct nfs_fh *new_dir, const char *new_name);
  11958. +extern int nfs_proc_link(struct nfs_server *server, struct nfs_fh *fhandle,
  11959. +             struct nfs_fh *dir, const char *name);
  11960. +extern int nfs_proc_symlink(struct nfs_server *server, struct nfs_fh *dir,
  11961. +                const char *name, const char *path, struct nfs_sattr *sattr);
  11962. +extern int nfs_proc_mkdir(struct nfs_server *server, struct nfs_fh *dir,
  11963. +              const char *name, struct nfs_sattr *sattr,
  11964. +              struct nfs_fh *fhandle, struct nfs_fattr *fattr);
  11965. +extern int nfs_proc_rmdir(struct nfs_server *server, struct nfs_fh *dir,
  11966. +              const char *name);
  11967. +extern int nfs_proc_readdir(struct nfs_server *server, struct nfs_fh *fhandle,
  11968. +                int cookie, int count, struct nfs_entry *entry);
  11969. +extern int nfs_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle,
  11970. +                struct nfs_fsinfo *res);
  11971. +
  11972. +/* linux/fs/nfs/sock.c */
  11973. +
  11974. +extern int nfs_rpc_call(struct nfs_server *server, int *start, int *end);
  11975. +
  11976. +/* linux/fs/nfs/inode.c */
  11977. +
  11978. +extern struct super_block *nfs_read_super(struct super_block *sb, 
  11979. +                      void *data,int);
  11980. +extern struct inode *nfs_fhget(struct super_block *sb, struct nfs_fh *fhandle,
  11981. +                   struct nfs_fattr *fattr);
  11982. +extern void nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr);
  11983. +
  11984. +/* linux/fs/nfs/file.c */
  11985. +
  11986. +extern struct inode_operations nfs_file_inode_operations;
  11987. +
  11988. +/* linux/fs/nfs/dir.c */
  11989. +
  11990. +extern struct inode_operations nfs_dir_inode_operations;
  11991. +
  11992. +/* linux/fs/nfs/symlink.c */
  11993. +
  11994. +extern struct inode_operations nfs_symlink_inode_operations;
  11995. +
  11996. +/* linux/fs/nfs/mmap.c */
  11997. +
  11998. +extern int nfs_mmap(struct inode * inode, struct file * file,
  11999. +               unsigned long addr, size_t len, int prot, unsigned long off);
  12000. +
  12001. +#endif
  12002. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/include/linux/nfs_mount.h linux-0.9pl4/include/linux/nfs_mount.h
  12003. --- linux-0.9pl3/include/linux/nfs_mount.h    Wed Dec 31 19:00:00 1969
  12004. +++ linux-0.9pl4/include/linux/nfs_mount.h    Wed Dec  1 07:44:15 1993
  12005. @@ -0,0 +1,48 @@
  12006. +#ifndef _LINUX_NFS_MOUNT_H
  12007. +#define _LINUX_NFS_MOUNT_H
  12008. +
  12009. +/*
  12010. + *  linux/include/linux/nfs_mount.h
  12011. + *
  12012. + *  Copyright (C) 1992  Rick Sladkey
  12013. + *
  12014. + *  structure passed from user-space to kernel-space during an nfs mount
  12015. + */
  12016. +
  12017. +/*
  12018. + * WARNING!  Do not delete or change the order of these fields.  If
  12019. + * a new field is required then add it to the end.  The version field
  12020. + * tracks which fields are present.  This will ensure some measure of
  12021. + * mount-to-kernel version compatibilty.  Some of these aren't used yet
  12022. + * but here they are anyway.
  12023. + */
  12024. +
  12025. +#define NFS_MOUNT_VERSION    1    /* current version */
  12026. +
  12027. +struct nfs_mount_data {
  12028. +    int version;            /* 1 */
  12029. +    int fd;                /* 1 */
  12030. +    struct nfs_fh root;        /* 1 */
  12031. +    int flags;            /* 1 */
  12032. +    int rsize;            /* 1 */
  12033. +    int wsize;            /* 1 */
  12034. +    int timeo;            /* 1 */
  12035. +    int retrans;            /* 1 */
  12036. +    int acregmin;            /* 1 */
  12037. +    int acregmax;            /* 1 */
  12038. +    int acdirmin;            /* 1 */
  12039. +    int acdirmax;            /* 1 */
  12040. +    struct sockaddr_in addr;    /* 1 */
  12041. +    char hostname[256];        /* 1 */
  12042. +};
  12043. +
  12044. +/* bits in the flags field */
  12045. +
  12046. +#define NFS_MOUNT_SOFT        0x0001    /* 1 */
  12047. +#define NFS_MOUNT_INTR        0x0002    /* 1 */
  12048. +#define NFS_MOUNT_SECURE    0x0004    /* 1 */
  12049. +#define NFS_MOUNT_POSIX        0x0008    /* 1 */
  12050. +#define NFS_MOUNT_NOCTO        0x0010    /* 1 */
  12051. +#define NFS_MOUNT_NOAC        0x0020    /* 1 */
  12052. +#endif
  12053. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/include/linux/wait.h linux-0.9pl4/include/linux/wait.h
  12054. --- linux-0.9pl3/include/linux/wait.h    Sun Aug 14 10:29:35 1994
  12055. +++ linux-0.9pl4/include/linux/wait.h    Sat Nov  5 11:41:43 1994
  12056. @@ -23,6 +23,7 @@
  12057.  };
  12058.  
  12059.  #define MUTEX ((struct semaphore) { 1, NULL })
  12060. +#define MUTEX_LOCKED ((struct semaphore) { 0, NULL })
  12061.  
  12062.  struct select_table_entry {
  12063.      struct wait_queue wait;
  12064. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/init/main.c linux-0.9pl4/init/main.c
  12065. --- linux-0.9pl3/init/main.c    Sun Aug 14 10:29:10 1994
  12066. +++ linux-0.9pl4/init/main.c    Thu Nov 24 22:17:11 1994
  12067. @@ -164,6 +164,7 @@
  12068.  static char command_line[COMMAND_LINE_SIZE] = { 0, };
  12069.  
  12070.  struct bootinfo boot_info = {0,};
  12071. +int bisize = sizeof boot_info;
  12072.  
  12073.  char *get_options(char *str, int *ints)
  12074.  {
  12075. @@ -329,7 +330,7 @@
  12076.              for (n = 0 ; devnames[n] ; n++) {
  12077.                  int len = strlen(devnames[n]);
  12078.                  if (!strncmp(line,devnames[n],len)) {
  12079. -                    ROOT_DEV = devnums[n]+simple_strtoul(line+len,NULL,16);
  12080. +                    ROOT_DEV = devnums[n]+simple_strtoul(line+len,NULL,10);
  12081.                      break;
  12082.                  }
  12083.              }
  12084. @@ -561,7 +562,7 @@
  12085.  #ifdef __i386__
  12086.      sprintf(term, "TERM=con%dx%d", ORIG_VIDEO_COLS, ORIG_VIDEO_LINES);
  12087.  #else
  12088. -    sprintf(term, "TERM=vt100");
  12089. +    sprintf(term, "TERM=console");
  12090.  #endif
  12091.      (void) open("/dev/tty1",O_RDWR,0);
  12092.      (void) dup(0);
  12093. @@ -576,6 +577,7 @@
  12094.          close(0);
  12095.          if (open("/etc/rc",O_RDONLY,0))
  12096.              _exit(1);
  12097. +
  12098.          execve("/bin/sh",argv_rc,envp_rc);
  12099.          _exit(2);
  12100.      }
  12101. @@ -595,6 +597,7 @@
  12102.              (void) dup(0);
  12103.              _exit(execve("/bin/sh",argv,envp));
  12104.          }
  12105. +
  12106.          while (1)
  12107.              if (pid == wait(&i))
  12108.                  break;
  12109. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/kernel/printk.c linux-0.9pl4/kernel/printk.c
  12110. --- linux-0.9pl3/kernel/printk.c    Sun Aug 14 10:30:34 1994
  12111. +++ linux-0.9pl4/kernel/printk.c    Mon Nov 21 18:09:04 1994
  12112. @@ -179,7 +179,10 @@
  12113.              if (log_size < LOG_BUF_LEN)
  12114.                  log_size++;
  12115.              else
  12116. +              {
  12117.                  log_start++;
  12118. +                log_start &= LOG_BUF_LEN - 1;
  12119. +              }
  12120.              logged_chars++;
  12121.              if (*p == '\n')
  12122.                  break;
  12123. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/m68k/head.S linux-0.9pl4/m68k/head.S
  12124. --- linux-0.9pl3/m68k/head.S    Tue Sep 27 22:24:23 1994
  12125. +++ linux-0.9pl4/m68k/head.S    Mon Nov 21 18:30:44 1994
  12126. @@ -9,6 +9,9 @@
  12127.  ** Atari support by Andreas Schwab, using ideas of Robert de Vries
  12128.  ** and Bjoern Brauel
  12129.  **
  12130. +** 94/11/14 Andreas Schwab: put kernel at KSTART_ADDR + PAGESIZE
  12131. +** 94/11/18 Andreas Schwab: remove identity mapping of STRAM for Atari 
  12132. +**
  12133.  ** This file is subject to the terms and conditions of the GNU General Public
  12134.  ** License.  See the file README.legal in the main directory of this archive
  12135.  ** for more details.
  12136. @@ -37,7 +40,7 @@
  12137.   */
  12138.  
  12139.  .text
  12140. -.globl _start, _krt, _kpt, _availmem
  12141. +.globl _krt, _kpt, _availmem
  12142.  
  12143.  PAGESIZE = 4096
  12144.  KSTART_ADDR = 0xC0000000
  12145. @@ -103,6 +106,24 @@
  12146.      movel    d0,sp
  12147.  
  12148.  /*
  12149. + * Copy bootinfo from position after BSS to final resting place
  12150. + */
  12151. +    lea    pc@(_end),a0
  12152. +    lea    pc@(_boot_info),a1
  12153. +    movel    pc@(_bisize),d0
  12154. +    subql    #1,d0
  12155. +1:    moveb    a0@+,a1@+
  12156. +    dbra    d0,1b
  12157. +
  12158. +/*
  12159. + * Record the CPU and machine type.
  12160. + */
  12161. +    lea    pc@(_boot_info),a0
  12162. +    lea    pc@(_end),a0
  12163. +    movel    a0@(BI_CPU),d6
  12164. +    movel    a0@(BI_MACH),d4
  12165. +
  12166. +/*
  12167.   * Initialize serial port
  12168.   */
  12169.      bsr Lserial_init
  12170. @@ -115,13 +136,6 @@
  12171.      bsr    Lserial_putc
  12172.  
  12173.  /*
  12174. - * Record the CPU and machine type.
  12175. - */
  12176. -    lea    pc@(_boot_info),a0
  12177. -    movel    a0@(BI_CPU),d6
  12178. -    movel    a0@(BI_MACH),d4
  12179. -
  12180. -/*
  12181.   * Get address at end of kernel code/data/bss and
  12182.   * mask off at a page boundary.
  12183.   */
  12184. @@ -197,7 +211,7 @@
  12185.      bnes    1f
  12186.  
  12187.      /* 680[23]0 */
  12188. -    lea    pc@(_start:w),a1  /* base address */
  12189. +    lea    pc@(_start-PAGESIZE:w),a1  /* base address */
  12190.      addql    #PAGEDESC,a1    /* descriptor type */
  12191.      movel    #0x40000,d2    /* increment */
  12192.      bras    2f
  12193. @@ -232,7 +246,7 @@
  12194.      bsr    Lserial_putc
  12195.  
  12196.      movel    pc@(_kpt),a0
  12197. -    lea    pc@(_start),a1
  12198. +    lea    pc@(_start-PAGESIZE:w),a1
  12199.      addw    #(GLOBAL+CM_CACHE_CB+PAGEDESC),a1
  12200.      movew    #((PAGESIZE/4)-1),d1
  12201.      movel    #PAGESIZE,d2
  12202. @@ -248,7 +262,7 @@
  12203.       * all pointer tables utilitized thus far) and the
  12204.       * kernel page table.
  12205.       */
  12206. -    lea    pc@(_start),a0
  12207. +    lea    pc@(_start-PAGESIZE:w),a0
  12208.      movel    a5,d0        /* address of root table */
  12209.      subl    a0,d0        /* determine offset of root table page */
  12210.      moveq    #PAGE_INDEX_SHIFT,d1    /* determine offset into kernel page table */
  12211. @@ -356,7 +370,7 @@
  12212.       * noncachable/serialized.
  12213.       */
  12214.      movel    a3,d0        /* ami page table start address */
  12215. -    lea    pc@(_start:w),a0
  12216. +    lea    pc@(_start-PAGESIZE:w),a0
  12217.      subl    a0,d0        /* determine offset of root table page */
  12218.      moveq    #12,d1        /* determine offset into kernel page table */
  12219.      lsrl    d1,d0
  12220. @@ -381,10 +395,10 @@
  12221.  
  12222.  /* On the Atari, duplicate the i/o region at 0xfffxxxxx and
  12223.     mark it non-cachable, set up an identity translation of the first
  12224. -   16M.  We need two additional page tables for this */
  12225. +   16M.  We need two additional pointer tables for this */
  12226.  
  12227.      lea    a5@(1024),a0
  12228. -    addl    #2,a0
  12229. +    addl    #TABLEDESC,a0
  12230.      movel    a0,a5@(508)        /* 0xFE000000 - 0xFFFFFFFF */
  12231.  
  12232.      lea     a5@(1024),a0
  12233. @@ -393,8 +407,8 @@
  12234.  1:    movel    d0,a0@+
  12235.      dbra    d2,1b
  12236.  
  12237. -/* Identity mapping of the last 16M of virtual address space
  12238. -   to the first 16M for efficient addressing of hardware registers */
  12239. +/* Mapping of the last 16M of virtual address space to the first 16M
  12240. +   for efficient addressing of hardware registers */
  12241.      movel    #0x40000,d1
  12242.      movel    #63,d2
  12243.      movel    #PAGEDESC,d0
  12244. @@ -409,6 +423,7 @@
  12245.      lea    a5@(1536+TABLEDESC),a0
  12246.      movel    a0,a5@
  12247.  
  12248. +#if 0 /* this is not needed any more */
  12249.  /* Identity mapping of the first 16M of virtual address space */
  12250.      lea    a5@(1536),a0
  12251.      movel    #PAGEDESC,d0
  12252. @@ -427,6 +442,7 @@
  12253.      movel    #63,d2
  12254.  1:    movel    d0,a0@+
  12255.      dbra    d2,1b
  12256. +#endif
  12257.  
  12258.      bra    Lmapphys
  12259.  
  12260. @@ -462,7 +478,7 @@
  12261.                   */
  12262.  
  12263.  2:
  12264. -    lea    pc@(_start:w),a0  /* get address of start of memory */
  12265. +    lea    pc@(_start-PAGESIZE:w),a0  /* get address of start of memory */
  12266.      cmpl    a0,d0        /* compare limit to start */
  12267.      bhi    Lnophys
  12268.  
  12269. @@ -478,7 +494,7 @@
  12270.       * in the root table.  a0 contains the start address of the
  12271.       * kernel.
  12272.       */
  12273. -    lea    pc@(_start:w),a0
  12274. +    lea    pc@(_start-PAGESIZE:w),a0
  12275.      movel    a0,d2
  12276.      moveq    #25,d3        /* find appropriate index in root table */
  12277.      lsrl    d3,d2
  12278. @@ -493,7 +509,7 @@
  12279.       * registers to identity map the 16M chunk that contains
  12280.       * the physical memory.
  12281.       */
  12282. -    lea    pc@(_start:w),a0
  12283. +    lea    pc@(_start-PAGESIZE:w),a0
  12284.      movel    a0,d2
  12285.      andl    #0xff000000,d2        /* logical address base */
  12286.      orw    #0xc040,d2        /* add in magic bits */
  12287. @@ -504,31 +520,20 @@
  12288.      cmpl    #MACH_ATARI,d4
  12289.      bnes    Lnophys2
  12290.  
  12291. -    /* if kernel runs in tt-ram, identity map its address space,
  12292. -       to be removed later */
  12293. -
  12294. -    lea    pc@(_start:w),a1
  12295. -    cmpl    #0x1000000,a1
  12296. -    bcs    Lnophys2
  12297. +    /* Temporarily set up an identity mapping of the 32MB chunk
  12298. +       where the kernel is executing */
  12299.  
  12300.      /* cleanup is needed; note it */
  12301.      moveq    #1,d5
  12302.  
  12303. -    /* this assumes that the kernel is in the first 12M of tt-ram,
  12304. -       otherwise we would have to set up an additional pointer table */
  12305. -    movel    a1,d2
  12306. -    moveq    #18,d3        /* find appropriate index in pointer table */
  12307. +    lea    pc@(_start-PAGESIZE:w),a0
  12308. +    movel    a0,d2
  12309. +    moveq    #25,d3        /* find appropriate index in root table */
  12310.      lsrl    d3,d2
  12311.      movel    d2,d0
  12312.      lsll    d3,d0        /* convert address into descriptor */
  12313.      addql    #PAGEDESC,d0
  12314. -    movel    #1<<18,d1
  12315. -    lea    a5@(1536),a0
  12316. -    lea    a0@(d2:l:4),a0
  12317. -    moveq    #15,d2
  12318. -1:    movel    d0,a0@+        /* store mapping */
  12319. -    addl    d1,d0
  12320. -    dbra    d2,1b
  12321. +    movel    d0,a5@(d2:l:4)  /* store mapping */
  12322.  
  12323.  Lnophys2:
  12324.  
  12325. @@ -542,7 +547,7 @@
  12326.      moveq    #'K',d7
  12327.      bsr    Lserial_putc
  12328.  
  12329. -    lea    pc@(Lmmu),a0
  12330. +    lea    pc@(mmu),a0
  12331.      movel    #0x80000002,a0@   /* no limit, 4byte descriptors */
  12332.      movel    a5,a0@(4)
  12333.      pmove    a0@,srp
  12334. @@ -577,7 +582,7 @@
  12335.      bsr    Lserial_putc
  12336.  
  12337.      movel    #KSTART_ADDR,d0
  12338. -    lea    pc@(_start:w),a0
  12339. +    lea    pc@(_start-PAGESIZE:w),a0
  12340.  
  12341.      movel    _kpt,d1
  12342.      subl    a0,d1
  12343. @@ -609,7 +614,7 @@
  12344.       lea       pc@(tmp_fault_handler),a0
  12345.       move.l    a0,8                     /* Access fault vector */
  12346.  
  12347. -    lea    pc@(_start:w),a0
  12348. +    lea    pc@(_start-PAGESIZE:w),a0
  12349.      jmp    Lvirt:l
  12350.  
  12351.  Lvirt:
  12352. @@ -628,30 +633,17 @@
  12353.  
  12354.      /* clean up physical identity mapping for 68020/68030 */
  12355.      cmpl    #MACH_AMIGA,d4
  12356. -    bne    Lnoamiclean
  12357. +    beqs    Lclean030
  12358. +    cmpl    #MACH_ATARI,d4
  12359. +    bnes    Lnoclean
  12360.  
  12361. +Lclean030:
  12362.      movel    a0,d2        /* a0 contains physical start address */
  12363.      moveq    #25,d3        /* find appropriate index in root table */
  12364.      lsrl    d3,d2
  12365.      moveq    #0,d0
  12366.      movel    d0,a5@(d2:l:4)  /* clear descriptor */
  12367.  
  12368. -Lnoamiclean:
  12369. -
  12370. -    cmpl    #MACH_ATARI,d4
  12371. -    bne    Lnoclean
  12372. -
  12373. -    movel    a0,d2        /* a0 contains physical start address */
  12374. -    moveq    #18,d3        /* find appropriate index in pointer table */
  12375. -    lsrl    d3,d2
  12376. -    moveq    #0,d0
  12377. -    lea    a5@(1536),a1
  12378. -    lea    a1@(d2:l:4),a1
  12379. -    moveq    #15,d5
  12380. -1:    movel    d0,a1@+        /* clear descriptor */
  12381. -    dbra    d5,1b
  12382. -
  12383. -    pflusha         /* flush address translation cache */
  12384.      bras    Lnoclean
  12385.  
  12386.  Loff040:
  12387. @@ -956,7 +948,7 @@
  12388.      moveq    #'=',d7
  12389.      bsr    Lserial_putc
  12390.  
  12391. -    lea    pc@(Lmmu),a1
  12392. +    lea    pc@(mmu),a1
  12393.      pmove    psr,a1@
  12394.      clrl    d7
  12395.      movew    a1@,d7
  12396. @@ -971,7 +963,7 @@
  12397.      rts
  12398.  
  12399.      .data
  12400. -Lmmu:    .quad 0
  12401. +mmu:    .quad 0
  12402.  _krt:    .long 0
  12403.  _kpt:    .long 0
  12404.  _availmem:
  12405. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/m68k/ints.c linux-0.9pl4/m68k/ints.c
  12406. --- linux-0.9pl3/m68k/ints.c    Sun Aug 14 10:29:37 1994
  12407. +++ linux-0.9pl4/m68k/ints.c    Sat Nov 12 09:51:47 1994
  12408. @@ -167,7 +167,7 @@
  12409.      }
  12410.  }
  12411.  
  12412. -#define    DEBUG_LOST_INT_DECR
  12413. +#undef DEBUG_LOST_INT_DECR
  12414.  
  12415.  asmlinkage void process_int(int level, struct intframe *fp)
  12416.  {
  12417. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/m68k/signal.c linux-0.9pl4/m68k/signal.c
  12418. --- linux-0.9pl3/m68k/signal.c    Sun Aug 14 10:29:37 1994
  12419. +++ linux-0.9pl4/m68k/signal.c    Thu Oct 20 22:51:01 1994
  12420. @@ -308,6 +308,40 @@
  12421.              current->state = TASK_STOPPED;
  12422.              notify_parent(current);
  12423.              schedule();
  12424. +            /* ++andreas: discard the extra stuff from the
  12425. +               stack frame and always return with a four-word
  12426. +               frame. */
  12427. +            switch (regs->format)
  12428. +              {
  12429. +              case 0:
  12430. +                break;
  12431. +              case 2:
  12432. +                regs->stkadj = sizeof (regs->un.fmt2);
  12433. +                break;
  12434. +              case 3:
  12435. +                regs->stkadj = sizeof (regs->un.fmt3);
  12436. +                break;
  12437. +              case 4:
  12438. +                regs->stkadj = sizeof (regs->un.fmt4);
  12439. +                break;
  12440. +              case 7:
  12441. +                regs->stkadj = sizeof (regs->un.fmt7);
  12442. +                break;
  12443. +              case 9:
  12444. +                regs->stkadj = sizeof (regs->un.fmt9);
  12445. +                break;
  12446. +              case 10:
  12447. +                regs->stkadj = sizeof (regs->un.fmta);
  12448. +                break;
  12449. +              case 11:
  12450. +                regs->stkadj = sizeof (regs->un.fmtb);
  12451. +                break;
  12452. +              default:
  12453. +                printk ("do_signal: Unknown frame format %#x\n",
  12454. +                    regs->format);
  12455. +                do_exit (SIGSEGV);
  12456. +              }
  12457. +            regs->format = 0;
  12458.              if (!(signr = current->exit_code))
  12459.                  continue;
  12460.              current->exit_code = 0;
  12461. @@ -374,7 +408,23 @@
  12462.          regs->pc -= 2;
  12463.      }
  12464.      if (!handler_signal)    /* no handler will be called - return 0 */
  12465. +      {
  12466. +        /* If we are about to discard some frame stuff we must
  12467. +           copy over the remaining frame. */
  12468. +        if (regs->stkadj)
  12469. +          {
  12470. +        struct frame *tregs =
  12471. +          (struct frame *) ((ulong) regs + regs->stkadj);
  12472. +
  12473. +        /* This must be copied with decreasing addresses to
  12474. +           handle overlaps.  */
  12475. +        tregs->format = regs->format;
  12476. +        tregs->vector = regs->vector;
  12477. +        tregs->pc = regs->pc;
  12478. +        tregs->sr = regs->sr;
  12479. +          }
  12480.          return 0;
  12481. +      }
  12482.      pc = regs->pc;
  12483.      frame = (unsigned long *)regs->usp;
  12484.      signr = 1;
  12485. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/m68k/sys_call.S linux-0.9pl4/m68k/sys_call.S
  12486. --- linux-0.9pl3/m68k/sys_call.S    Sun Aug 28 17:16:21 1994
  12487. +++ linux-0.9pl4/m68k/sys_call.S    Sat Nov 12 09:52:25 1994
  12488. @@ -90,6 +90,17 @@
  12489.  LTS_FLAGS    = 20
  12490.  LTS_ERRNO    = 24
  12491.  
  12492. +#include <linux/autoconf.h>
  12493. +
  12494. +/* the following macro is used when enabling interrupts */
  12495. +#if defined(CONFIG_ATARI) && !defined(CONFIG_AMIGA) && !defined(CONFIG_MAC)
  12496. +    /* block out HSYNC on the atari */
  12497. +#define ALLOWINT 0xfbff
  12498. +#else
  12499. +    /* portable version */
  12500. +#define ALLOWINT 0xf8ff
  12501. +#endif /* machine compilation types */ 
  12502. +
  12503.  .globl _system_call, _buserr, _trap
  12504.  .globl _ret_from_exception, _inthandler
  12505.  
  12506. @@ -280,12 +291,12 @@
  12507.      bne    1f
  12508.  
  12509.      movel    _bh_mask,d0
  12510. -    andl    d0,_bh_active
  12511. +    andl    _bh_active,d0
  12512.      beq    1f
  12513.  
  12514.      movew    sr,sp@-
  12515.      addql    #1,_intr_count
  12516. -    andiw    #0xf8ff,sr        | allow interrupts
  12517. +    andiw    #(ALLOWINT),sr        | allow interrupts
  12518.      jbsr    _do_bottom_half
  12519.      movew    sp@+,sr
  12520.      subql    #1,_intr_count
  12521. @@ -311,7 +322,7 @@
  12522.  Lnotkernel:
  12523.      addql    #8,sp            | throw away throwaway stack frame
  12524.      oriw    #0x1000,sr        | set master bit in SR (sp is now msp)
  12525. -    andiw    #0xf8ff,sr        | allow interrupts
  12526. +    andiw    #(ALLOWINT),sr        | allow interrupts
  12527.      clrw    sp@-            | stack adjustment
  12528.      subql    #8,sp            | make room for usp and orig_d0
  12529.      movel    d0,sp@-         | save registers as for syscall
  12530. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/m68k/traps.c linux-0.9pl4/m68k/traps.c
  12531. --- linux-0.9pl3/m68k/traps.c    Sun Aug 28 17:16:21 1994
  12532. +++ linux-0.9pl4/m68k/traps.c    Mon Nov 21 18:09:06 1994
  12533. @@ -284,13 +284,13 @@
  12534.      printk ("SSW=%#06x  ", ssw);
  12535.  
  12536.      if (ssw & (FC | FB))
  12537. -        printk ("Instruction fault at %#010x\n",
  12538. +        printk ("Instruction fault at %#010lx\n",
  12539.              ssw & FC ?
  12540.              fp->format == 0xa ? fp->pc + 2 : fp->un.fmtb.baddr - 2
  12541.              :
  12542.              fp->format == 0xa ? fp->pc + 4 : fp->un.fmtb.baddr);
  12543.      if (ssw & DF)
  12544. -        printk ("Data %s fault at %#010x in %s (pc=%#lx)\n",
  12545. +        printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n",
  12546.              ssw & RW ? "read" : "write",
  12547.              fp->un.fmtb.daddr,
  12548.              space_names[ssw & DFC], fp->pc);
  12549. @@ -393,7 +393,7 @@
  12550.             (but only if the page is now valid).  Otherwise we'll get
  12551.             an wierd read access.  */
  12552.      /* XXX can this condition be simplified? */
  12553. -    if (ssw & DF && ssw & RB && mmusr & MMU_I
  12554. +    if (ssw & DF && ssw & RB && (mmusr & MMU_I)
  12555.          && (addr & PAGE_MASK) == (fp->un.fmtb.baddr & PAGE_MASK))
  12556.        {
  12557.          asm volatile ("ptestr #1,%1@,#7\n\t"
  12558. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/mm/memory.c linux-0.9pl4/mm/memory.c
  12559. --- linux-0.9pl3/mm/memory.c    Sun Aug 14 10:29:39 1994
  12560. +++ linux-0.9pl4/mm/memory.c    Mon Nov 21 18:32:45 1994
  12561. @@ -85,7 +85,7 @@
  12562.  
  12563.  /*
  12564.   * oom() prints a message (so that the user knows why the process died),
  12565. - * and gives the process an untrappable SIGSEGV.
  12566. + * and gives the process an untrappable SIGKILL.
  12567.   */
  12568.  void oom(struct task_struct * task)
  12569.  {
  12570. @@ -271,7 +271,9 @@
  12571.          panic("Trying to free up swapper memory space");
  12572.      }
  12573.      root = tsk->tss.pagedir_v;
  12574. -    if (!root || root == task[0]->tss.pagedir_v) {
  12575. +    if (!root)
  12576. +      return;
  12577. +    if (root == task[0]->tss.pagedir_v) {
  12578.          printk("Trying to free kernel root table: not good\n");
  12579.          return;
  12580.      }
  12581. @@ -291,6 +293,8 @@
  12582.       */
  12583.      if (root[NUM_L1_ENTRIES-1] > 0) {
  12584.          root[NUM_L1_ENTRIES-1]--;
  12585. +        tsk->tss.pagedir_v = 0;
  12586. +        tsk->tss.pagedir_p = 0;
  12587.          return;
  12588.      }
  12589.  
  12590. @@ -338,11 +342,11 @@
  12591.  }
  12592.  
  12593.  static int copy_pointer_table (struct task_struct *tsk,
  12594. -                   unsigned long old_ptr_desc,
  12595. +                   unsigned long *old_ptr_table,
  12596.                     unsigned long *new_root)
  12597.  {
  12598.      int i;
  12599. -    unsigned long *old_ptr_table, *new_ptr_table, new_ptr_vaddr;
  12600. +    unsigned long *new_ptr_table, new_ptr_vaddr;
  12601.  
  12602.      /* get a new pointer table, can't allocate, no fork */
  12603.      if (!(new_ptr_table = get_pointer_table ())) {
  12604. @@ -352,13 +356,12 @@
  12605.      new_ptr_vaddr = (unsigned long)new_ptr_table;
  12606.  
  12607.      /* process each page table in the pointer table */
  12608. -    old_ptr_table = (unsigned long *)PTOV(old_ptr_desc & TABLE_MASK);
  12609. -
  12610.      for (i = 0 ; i < NUM_L2_ENTRIES ;
  12611.           i++,old_ptr_table += 16, new_ptr_table += 16) {
  12612.          int j;
  12613.          unsigned long old_pg_table, *old_page_tablep;
  12614.          unsigned long *new_page_tablep;
  12615. +        unsigned long old_pg_table_v;
  12616.  
  12617.          /* read descriptor for page table */
  12618.          old_pg_table = *old_ptr_table;
  12619. @@ -371,7 +374,8 @@
  12620.           * if the address is too high, or it is not a short
  12621.           * descriptor, things are screwy.
  12622.           */
  12623. -        if (PTOV(old_pg_table) >= high_memory
  12624. +        old_pg_table_v = PTOV (old_pg_table & PAGE_MASK);
  12625. +        if (old_pg_table_v >= high_memory
  12626.              || !(old_pg_table & PAGE_TABLE)) {
  12627.              printk("copy_page_tables: bad page table: "
  12628.                     "probable memory corruption\n");
  12629. @@ -383,7 +387,7 @@
  12630.           * if it is a reserved entry (won't be, with the separate kernel
  12631.           * and user virtual address spaces for the M68K port.
  12632.           */
  12633. -        if (mem_map[MAP_NR(PTOV(old_pg_table))] & MAP_PAGE_RESERVED) {
  12634. +        if (mem_map[MAP_NR(old_pg_table_v)] & MAP_PAGE_RESERVED) {
  12635.              *new_ptr_table = old_pg_table;
  12636.              continue;
  12637.          }
  12638. @@ -393,9 +397,9 @@
  12639.              return -ENOMEM;
  12640.  
  12641.          /* process each page in the page table */
  12642. -        old_page_tablep = (unsigned long *)PTOV(old_pg_table & PAGE_MASK);
  12643. +        old_page_tablep = (unsigned long *) old_pg_table_v;
  12644.          for (j = 0 ; j < PTRS_PER_PAGE ; j++,old_page_tablep++,new_page_tablep++) {
  12645. -            unsigned long pg;
  12646. +            unsigned long pg, pg_v;
  12647.  
  12648.              /* read page descriptor from table */
  12649.              pg = *old_page_tablep;
  12650. @@ -417,10 +421,11 @@
  12651.              if ((pg & (PAGE_RONLY | PAGE_COW)) == PAGE_COW)
  12652.                  pg |= PAGE_RONLY;
  12653.              *new_page_tablep = pg;
  12654. -            if (mem_map[MAP_NR(PTOV(pg & PAGE_MASK))] & MAP_PAGE_RESERVED)
  12655. +            pg_v = PTOV (pg & PAGE_MASK);
  12656. +            if (mem_map[MAP_NR(pg_v)] & MAP_PAGE_RESERVED)
  12657.                  continue;
  12658.              *old_page_tablep = pg;
  12659. -            mem_map[MAP_NR(PTOV(pg & PAGE_MASK))]++;
  12660. +            mem_map[MAP_NR(pg_v)]++;
  12661.          }
  12662.      }
  12663.  
  12664. @@ -460,6 +465,7 @@
  12665.  
  12666.      for (i = 0 ; i < NUM_L1_ENTRIES-1 ; i++, old_root++,new_root++) {
  12667.          unsigned long old_ptr_desc;
  12668. +        unsigned long vaddr;
  12669.  
  12670.          /* read descriptor for pointer table */
  12671.          old_ptr_desc = *old_root;
  12672. @@ -472,7 +478,8 @@
  12673.           * if the address is too high, or it is not a short
  12674.           * descriptor, things are screwy.
  12675.           */
  12676. -        if (PTOV(old_ptr_desc) >= high_memory
  12677. +        vaddr = PTOV (old_ptr_desc & TABLE_MASK);
  12678. +        if (vaddr >= high_memory
  12679.              || !(old_ptr_desc & PAGE_TABLE)) {
  12680.              printk("copy_page_tables: bad pointer table: "
  12681.                     "probable memory corruption\n");
  12682. @@ -480,7 +487,7 @@
  12683.              continue;
  12684.          }
  12685.  
  12686. -        if (copy_pointer_table (tsk, old_ptr_desc, new_root))
  12687. +        if (copy_pointer_table (tsk, (unsigned long *)vaddr, new_root))
  12688.              return -ENOMEM;
  12689.      }
  12690.  end:
  12691. @@ -517,10 +524,11 @@
  12692.          if ((page = *page_table) != 0) {
  12693.              *page_table = 0;
  12694.              if (page & PAGE_PRESENT) {
  12695. -                if (!(mem_map[MAP_NR(PTOV(page & PAGE_MASK))] & MAP_PAGE_RESERVED))
  12696. +                unsigned long page_v = PTOV(page & PAGE_MASK);
  12697. +                if (!(mem_map[MAP_NR(page_v)] & MAP_PAGE_RESERVED))
  12698.                                          if (current->rss > 0)
  12699.                                                  --current->rss;
  12700. -                free_page(PTOV(page & PAGE_MASK));
  12701. +                free_page(page_v);
  12702.              } else
  12703.                  swap_free(page);
  12704.          }
  12705. @@ -572,10 +580,11 @@
  12706.          if ((page = *page_table) != 0) {
  12707.              *page_table = 0;
  12708.              if (page & PAGE_PRESENT) {
  12709. -                if (!(mem_map[MAP_NR(PTOV(page & PAGE_MASK))] & MAP_PAGE_RESERVED))
  12710. +                unsigned long page_v = PTOV(page & PAGE_MASK);
  12711. +                if (!(mem_map[MAP_NR(page_v)] & MAP_PAGE_RESERVED))
  12712.                                          if (current->rss > 0)
  12713.                                                  --current->rss;
  12714. -                free_page(PTOV(page & PAGE_MASK));
  12715. +                free_page(page_v);
  12716.              } else
  12717.                  swap_free(page);
  12718.          }
  12719. @@ -636,10 +645,11 @@
  12720.          if ((page = *page_table) != 0) {
  12721.              *page_table = 0;
  12722.              if (page & PAGE_PRESENT) {
  12723. -                if (!(mem_map[MAP_NR(PTOV(page & PAGE_MASK))] & MAP_PAGE_RESERVED))
  12724. +                unsigned long page_v = PTOV(page & PAGE_MASK);
  12725. +                if (!(mem_map[MAP_NR(page_v)] & MAP_PAGE_RESERVED))
  12726.                                          if (current->rss > 0)
  12727.                                                  --current->rss;
  12728. -                free_page(PTOV(page & PAGE_MASK));
  12729. +                free_page(page_v);
  12730.              } else
  12731.                  swap_free(page);
  12732.          }
  12733. @@ -652,7 +662,7 @@
  12734.           */
  12735.          if (!mask)
  12736.              *page_table = 0;    /* not present */
  12737. -        else if (to >= high_memory)
  12738. +        else if (to < KSTART_ADDR || to >= high_memory)
  12739.              *page_table = (VTOP(to) | mask);
  12740.          else if (!mem_map[MAP_NR(to)])
  12741.              *page_table = 0;    /* not present */
  12742. @@ -788,6 +798,7 @@
  12743.  {
  12744.      unsigned long *rootp, desc, *ptep, *ptrp, old_page, prot;
  12745.      unsigned long new_page;
  12746. +    unsigned long vaddr;
  12747.  
  12748.  #ifdef DEBUG
  12749.      if (user_usp)
  12750. @@ -797,27 +808,28 @@
  12751.      new_page = __get_free_page(GFP_KERNEL);
  12752.      rootp = &tsk->tss.pagedir_v[L1_INDEX(address)];
  12753.      desc = *rootp;
  12754. -    if ((desc & PAGE_TABLE) != PAGE_TABLE
  12755. -        || PTOV (desc & TABLE_MASK) >= high_memory)
  12756. +    vaddr = PTOV (desc & TABLE_MASK);
  12757. +    if ((desc & PAGE_TABLE) != PAGE_TABLE || vaddr >= high_memory)
  12758.          panic ("do_wp_page: invalid root table entry %08lx", desc);
  12759. -    ptrp = (unsigned long *)PTOV(desc & TABLE_MASK);
  12760. +    ptrp = (unsigned long *) vaddr;
  12761.      ptrp += L2_INDEX(address);
  12762.      desc = *ptrp;
  12763. -    if ((desc & PAGE_TABLE) != PAGE_TABLE
  12764. -        || PTOV (desc & TABLE_MASK) >= high_memory)
  12765. +    vaddr = PTOV (desc & PAGE_MASK);
  12766. +    if ((desc & PAGE_TABLE) != PAGE_TABLE || vaddr  >= high_memory)
  12767.          goto bad_wp_pagetable;
  12768. -    ptep = (unsigned long *)PTOV(desc & PAGE_MASK) + L3_INDEX(address);
  12769. +    ptep = (unsigned long *) vaddr + L3_INDEX(address);
  12770.      old_page = *ptep;
  12771.      if (!(old_page & PAGE_PRESENT))
  12772.          goto end_wp_page;
  12773. -    if (PTOV (old_page) >= high_memory)
  12774. +    vaddr = PTOV (old_page & PAGE_MASK);
  12775. +    if (vaddr >= high_memory)
  12776.          goto bad_wp_page;
  12777.      if (!(old_page & PAGE_RONLY))
  12778.          goto end_wp_page;
  12779.      /* minor page fault (copy on write) */
  12780.      tsk->min_flt++;
  12781.      prot = ((old_page & ~PAGE_MASK) & ~PAGE_RONLY) | PAGE_RW;
  12782. -    old_page = PTOV(old_page & PAGE_MASK);
  12783. +    old_page = vaddr;
  12784.      /* if page was used only once (no longer shared) enable read write */
  12785.      if (mem_map[MAP_NR(old_page)] != 1) {
  12786.          if (new_page) {
  12787. @@ -868,6 +880,7 @@
  12788.  {
  12789.      unsigned long page, ptrdesc;
  12790.      unsigned long *rootp, *pg_table;
  12791. +    unsigned long vaddr;
  12792.  
  12793.  #ifdef DEBUG
  12794.      printk ("do_wp_page (address=%#lx, user_usp=%#lx\n", address,
  12795. @@ -899,8 +912,9 @@
  12796.           */
  12797.          panic ("do_wp_page: unexplained null pointer table entry for %lx", address);
  12798.      }
  12799. -    if ((page & PAGE_TABLE) && PTOV(page) < high_memory) {
  12800. -        pg_table = (unsigned long *)PTOV(page & PAGE_MASK);
  12801. +    vaddr = PTOV (page & PAGE_MASK);
  12802. +    if ((page & PAGE_TABLE) && vaddr < high_memory) {
  12803. +        pg_table = (unsigned long *) vaddr;
  12804.          pg_table += L3_INDEX(address);
  12805.          page = *pg_table;
  12806.          if (!(page & PAGE_PRESENT))
  12807. @@ -1050,7 +1064,7 @@
  12808.      if (!inode || inode->i_count < 2 || !area->vm_ops)
  12809.          return 0;
  12810.      for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) {
  12811. -        if (!*p)
  12812. +        if (!*p || !(*p)->tss.pagedir_v)
  12813.              continue;
  12814.          if (tsk == *p)
  12815.              continue;
  12816. @@ -1368,6 +1382,11 @@
  12817.              do_no_page (error_code, address, current, user_esp);
  12818.          return;
  12819.      }
  12820. +    if ((fp->un.fmtb.ssw & 4) == 0) {
  12821. +        /* User memory access */
  12822. +        send_sig (SIGSEGV, current, 1);
  12823. +        return;
  12824. +    }
  12825.      printk("Unable to handle kernel paging request at address %08lx from %lx\n",address, fp->pc);
  12826.      die_if_kernel("Oops", fp, error_code);
  12827.      do_exit(SIGKILL);
  12828. @@ -1508,7 +1527,7 @@
  12829.      printk("Free pages:      %6dkB\n",nr_free_pages<<(PAGE_SHIFT-10));
  12830.      printk("Secondary pages: %6dkB\n",nr_secondary_pages<<(PAGE_SHIFT-10));
  12831.      printk("Free swap:       %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
  12832. -    i = (high_memory-0xC0000000) >> PAGE_SHIFT;
  12833. +    i = (high_memory-KSTART_ADDR) >> PAGE_SHIFT;
  12834.      while (i-- > 0) {
  12835.      total++;
  12836.      if (mem_map[i] & MAP_PAGE_RESERVED)
  12837. @@ -1555,6 +1574,69 @@
  12838.              offset += boot_info.memory[i].size;
  12839.      }
  12840.  
  12841. +    /* not in one of the memory chunks; get the actual
  12842. +     * physical address from the MMU.
  12843. +     */
  12844. +    if (boot_info.cputype & CPU_68040) {
  12845. +      unsigned long mmusr;
  12846. +      unsigned short fs = get_fs();
  12847. +
  12848. +      set_fs (SUPER_DATA);
  12849. +
  12850. +      asm volatile ("movel %1,a0\n\t"
  12851. +            ".word 0xf568\n\t"    /* ptestr (a0) */
  12852. +            ".long 0x4e7a8805\n\t"    /* movec mmusr, a0 */
  12853. +            "movel a0,%0"
  12854. +            : "=g" (mmusr)
  12855. +            : "g" (vaddr)
  12856. +            : "a0", "d0");
  12857. +      set_fs (fs);
  12858. +
  12859. +      if (mmusr & MMU_R_040)
  12860. +        return (mmusr & PAGE_MASK) | (vaddr & (PAGE_SIZE-1));
  12861. +
  12862. +      panic ("VTOP040: bad virtual address %08lx (%lx)", vaddr, mmusr);
  12863. +    } else {
  12864. +      volatile unsigned short temp;
  12865. +      unsigned short mmusr;
  12866. +      unsigned long *descaddr;
  12867. +
  12868. +      asm volatile ("ptestr #5,%2@,#7,%0\n\t"
  12869. +            "pmove psr,%1@"
  12870. +            : "=a&" (descaddr)
  12871. +            : "a" (&temp), "a" (vaddr));
  12872. +      mmusr = temp;
  12873. +
  12874. +      printk ("mmusr is %#x for kernel vaddr %#lx\n",
  12875. +          mmusr, vaddr);
  12876. +
  12877. +      if (mmusr & (MMU_I|MMU_B|MMU_L))
  12878. +        panic ("VTOP030: bad virtual address %08lx (%x)", vaddr, mmusr);
  12879. +
  12880. +      descaddr = (unsigned long *)PTOV(descaddr);
  12881. +
  12882. +      printk ("descriptor address is %p, contents %#lx\n",
  12883. +          descaddr, *descaddr);
  12884. +
  12885. +      switch (mmusr & MMU_NUM) {
  12886. +      case 1:
  12887. +        printk ("physaddr for %lx is %lx\n", vaddr,
  12888. +            (*descaddr & 0xfe000000) | (vaddr & 0x01ffffff));
  12889. +        return (*descaddr & 0xfe000000) | (vaddr & 0x01ffffff);
  12890. +      case 2:
  12891. +        printk ("physaddr for %lx is %lx\n", vaddr,
  12892. +            (*descaddr & 0xfffc0000) | (vaddr & 0x0003ffff));
  12893. +        return (*descaddr & PAGE_MASK) | (vaddr & 0x0003ffff);
  12894. +      case 3:
  12895. +        printk ("physaddr for %lx is %lx\n", vaddr,
  12896. +            (*descaddr & PAGE_MASK) | (vaddr & (PAGE_SIZE-1)));
  12897. +        return (*descaddr & PAGE_MASK) | (vaddr & (PAGE_SIZE-1));
  12898. +      default:
  12899. +        panic ("VTOP: bad levels (%d) for virtual address %08lx", 
  12900. +           mmusr & MMU_NUM, vaddr);
  12901. +      }
  12902. +    }
  12903. +
  12904.      panic ("VTOP: bad virtual address %08lx", vaddr);
  12905.  }
  12906.  
  12907. @@ -1577,8 +1659,21 @@
  12908.              offset += boot_info.memory[i].size;
  12909.      }
  12910.  
  12911. -    panic ("PTOV: bad physical address %08lx (called from %p)\n",
  12912. -           paddr, __builtin_return_address(0));
  12913. +    /*
  12914. +     * assume that the kernel virtual address is the same as the
  12915. +     * physical address.
  12916. +     *
  12917. +     * This should be reasonable in most situations:
  12918. +     *  1) They shouldn't be dereferencing the virtual address
  12919. +     *     unless they are sure that it is valid from kernel space.
  12920. +     *  2) The only usage I see so far is converting a page table
  12921. +     *     reference to some non-FASTMEM address space when freeing
  12922. +         *     mmaped "/dev/mem" pages.  These addresses are just passed
  12923. +     *     to "free_page", which ignores addresses that aren't in
  12924. +     *     the memory list anyway.
  12925. +     *
  12926. +     */
  12927. +    return paddr;
  12928.  }
  12929.  
  12930.  static unsigned long *kernel_pointer_table (void)
  12931. @@ -1968,7 +2063,7 @@
  12932.      virtual_start = availmem;
  12933.  
  12934.      /* virtual address of end of available memory */
  12935. -    virtual_end = (unsigned long)start + mem_avail;
  12936. +    virtual_end = KSTART_ADDR + mem_avail;
  12937.  
  12938.  #ifdef DEBUG
  12939.      printk ("virtual_start is %#lx\nvirtual_end is %#lx\n",
  12940. @@ -2060,6 +2155,37 @@
  12941.          start_mem += PAGE_SIZE;
  12942.      }
  12943.  
  12944. +#ifdef CONFIG_ATARI
  12945. +
  12946. +    if (boot_info.machtype == MACH_ATARI) {
  12947. +
  12948. +        /* If the page with physical address 0 isn't the first kernel
  12949. +         * code page, it has to be reserved because the first 2 KB of
  12950. +         * ST-Ram can only be accessed from supervisor mode by
  12951. +         * hardware.
  12952. +         */
  12953. +
  12954. +        unsigned long virt0 = PTOV( 0 ), adr;
  12955. +        extern unsigned long rsvd_stram_beg, rsvd_stram_end;
  12956. +        
  12957. +        if (virt0 != KSTART_ADDR) {
  12958. +
  12959. +            mem_map[MAP_NR(virt0)] = MAP_PAGE_RESERVED;
  12960. +
  12961. +            /* Also, reserve all pages that have been marked by
  12962. +             * stram_alloc() (e.g. for the screen memory). (This may
  12963. +             * treat the first ST-Ram page a second time, but that
  12964. +             * doesn't hurt...) */
  12965. +            
  12966. +            rsvd_stram_end += PAGE_SIZE - 1;
  12967. +            rsvd_stram_end &= PAGE_MASK;
  12968. +            rsvd_stram_beg &= PAGE_MASK;
  12969. +            for( adr = rsvd_stram_beg; adr < rsvd_stram_end; adr += PAGE_SIZE )
  12970. +                mem_map[MAP_NR(adr)] = MAP_PAGE_RESERVED;
  12971. +        }
  12972. +    }
  12973. +    
  12974. +#endif
  12975.  #ifdef DEBUG
  12976.      printk ("task[0] root table is %p\n", task[0]->tss.pagedir_v);
  12977.  #endif
  12978. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/mm/mmap.c linux-0.9pl4/mm/mmap.c
  12979. --- linux-0.9pl3/mm/mmap.c    Sun Aug 14 10:29:39 1994
  12980. +++ linux-0.9pl4/mm/mmap.c    Thu Nov 24 21:10:20 1994
  12981. @@ -48,6 +48,9 @@
  12982.  {
  12983.      int mask, error;
  12984.      
  12985. +    if ((len = PAGE_ALIGN(len)) == 0)
  12986. +        return addr;
  12987. +
  12988.      if (addr > TASK_SIZE || len > TASK_SIZE || addr > TASK_SIZE-len)
  12989.          return -EINVAL;
  12990.      
  12991. @@ -110,13 +113,15 @@
  12992.      if (file && (!file->f_op || !file->f_op->mmap))
  12993.          return -ENODEV;
  12994.      mask = 0;
  12995. -    if (prot & (PROT_READ | PROT_EXEC))
  12996. +    if (!(prot & PROT_WRITE))
  12997.          mask |= PAGE_READONLY;
  12998. -    if (prot & PROT_WRITE)
  12999. +    if (prot & PROT_WRITE) {
  13000. +        mask &= ~PAGE_READONLY;
  13001.          if ((flags & MAP_TYPE) == MAP_PRIVATE)
  13002.              mask |= PAGE_COPY;
  13003.          else
  13004.              mask |= PAGE_SHARED;
  13005. +    }
  13006.      if (!mask)
  13007.          return -EINVAL;
  13008.  
  13009. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/mm/swap.c linux-0.9pl4/mm/swap.c
  13010. --- linux-0.9pl3/mm/swap.c    Mon Sep 19 22:00:57 1994
  13011. +++ linux-0.9pl4/mm/swap.c    Mon Oct 10 16:48:32 1994
  13012. @@ -321,7 +321,6 @@
  13013.      int counter = NR_TASKS * 2 >> priority;
  13014.      struct task_struct *p;
  13015.  
  13016. -    counter = NR_TASKS * 2 >> priority;
  13017.      for(; counter >= 0; counter--, swap_task++) {
  13018.      /*
  13019.       * Check that swap_task is suitable for swapping.  If not, look for
  13020. @@ -366,30 +365,36 @@
  13021.      /* On the m68k, the last entry in the root table is the use
  13022.         count, it must not be touched */
  13023.      for(table = p->swap_table; table < 1024 - 8; table++) {
  13024. -        unsigned long desc, *ptr;
  13025. +        unsigned long desc, desc_p, *ptr;
  13026. +        unsigned long pg_table_p;
  13027.  
  13028. -        desc = L1_SWAP_INDEX(p->tss.pagedir_v,table);
  13029. -        if(!desc || PTOV(desc & TABLE_MASK) >= high_memory)
  13030. +        desc_p = L1_SWAP_INDEX(p->tss.pagedir_v,table);
  13031. +        if (!desc_p)
  13032.              continue;
  13033. -        if(!(PAGE_TABLE & desc)) {
  13034. +        desc = PTOV (desc_p & TABLE_MASK);
  13035. +        if (desc >= high_memory)
  13036. +            continue;
  13037. +        if (!(PAGE_TABLE & desc_p)) {
  13038.              printk("swap_out: bad page-table at pg_dir[%d]: %08lx\n",
  13039. -                table, desc);
  13040. +                table, desc_p);
  13041.              L1_SWAP_INDEX(p->tss.pagedir_v,table) = 0;
  13042.              continue;
  13043.          }
  13044. -        ptr = (unsigned long *)PTOV(desc & TABLE_MASK);
  13045. -        pg_table = L2_SWAP_INDEX(ptr,table);
  13046. -        if (!pg_table || PTOV(pg_table & PAGE_MASK) >= high_memory)
  13047. +        ptr = (unsigned long *) desc;
  13048. +        pg_table_p = L2_SWAP_INDEX(ptr,table);
  13049. +        if (!pg_table_p)
  13050.              continue;
  13051. -        if(mem_map[MAP_NR(PTOV(pg_table & PAGE_MASK))] & MAP_PAGE_RESERVED)
  13052. +        pg_table = PTOV (pg_table_p & PAGE_MASK);
  13053. +        if (pg_table >= high_memory)
  13054.              continue;
  13055. -        if(!(PAGE_TABLE & pg_table)) {
  13056. +        if (mem_map[MAP_NR(pg_table)] & MAP_PAGE_RESERVED)
  13057. +            continue;
  13058. +        if (!(PAGE_TABLE & pg_table_p)) {
  13059.              printk("swap_out: bad page-table at pg_dir[%d]: %08lx\n",
  13060. -                table, pg_table);
  13061. +                table, pg_table_p);
  13062.              L2_SWAP_INDEX(ptr,table) = 0;
  13063.              continue;
  13064.          }
  13065. -        pg_table = PTOV(pg_table & PAGE_MASK);
  13066.  
  13067.          /*
  13068.           * Go through this page table.
  13069. @@ -661,8 +666,8 @@
  13070.      if (intr_count && priority != GFP_ATOMIC) {
  13071.          static int count = 0;
  13072.          if (++count < 5) {
  13073. -            printk("gfp called nonatomically from interrupt %08lx\n",
  13074. -                ((unsigned long *)&priority)[-1]);
  13075. +            printk("gfp called nonatomically from interrupt %p\n",
  13076. +                __builtin_return_address (0));
  13077.              priority = GFP_ATOMIC;
  13078.          }
  13079.      }
  13080. @@ -703,19 +708,21 @@
  13081.              continue;
  13082.          for (pgt = 0 ; pgt < PTRS_PER_PAGE ; pgt++) {
  13083.              desc = L1_SWAP_INDEX(p->tss.pagedir_v,pgt);
  13084. -            if (!desc)
  13085. +            if (!desc || !(desc & PAGE_TABLE))
  13086.                  continue;
  13087. -            if (!(desc & PAGE_TABLE) || PTOV(desc & TABLE_MASK) >= high_memory)
  13088. +            desc = PTOV (desc & TABLE_MASK);
  13089. +            if (desc >= high_memory)
  13090.                  continue;
  13091. -            ptr = (unsigned long *)PTOV(desc & TABLE_MASK);
  13092. +            ptr = (unsigned long *) desc;
  13093.              page = L2_SWAP_INDEX(ptr,pgt);
  13094. -            if (!page)
  13095. +            if (!page || !(page & PAGE_TABLE))
  13096.                  continue;
  13097. -            if (!(page & PAGE_PRESENT) || (PTOV(page & PAGE_MASK) >= high_memory))
  13098. +            page = PTOV (page & PAGE_MASK);
  13099. +            if (page >= high_memory)
  13100.                  continue;
  13101. -            if (mem_map[MAP_NR(PTOV(page & PAGE_MASK))] & MAP_PAGE_RESERVED)
  13102. +            if (mem_map[MAP_NR(page)] & MAP_PAGE_RESERVED)
  13103.                  continue;
  13104. -            ppage = (unsigned long *) PTOV(page & PAGE_MASK);
  13105. +            ppage = (unsigned long *) page;
  13106.              for (pg = 0 ; pg < PTRS_PER_PAGE ; pg++,ppage++) {
  13107.                  page = *ppage;
  13108.                  if (!page)
  13109. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/mm/vmalloc.c linux-0.9pl4/mm/vmalloc.c
  13110. --- linux-0.9pl3/mm/vmalloc.c    Sun Aug 14 10:29:39 1994
  13111. +++ linux-0.9pl4/mm/vmalloc.c    Sat Nov  5 13:08:33 1994
  13112. @@ -137,8 +137,8 @@
  13113.      if (!(PAGE_TABLE & (ptr = krt[dindex >> 3])))
  13114.          return 0;
  13115.      ptrp = (unsigned long *)PTOV(ptr & TABLE_MASK);
  13116. -    ptrp += (16*sizeof(long))*(dindex & (NUM_L2_ENTRIES-1));
  13117. -    if (!(PAGE_TABLE & (page = ptrp[16*(dindex & (NUM_L2_ENTRIES-1))])))
  13118. +    ptrp += 16*(dindex & (NUM_L2_ENTRIES-1));
  13119. +    if (!(PAGE_TABLE & (page = *ptrp)))
  13120.          return 0;
  13121.      page = PTOV(page & PAGE_MASK);
  13122.      pte = index + (unsigned long *) page;
  13123. @@ -154,7 +154,7 @@
  13124.          if (*pte)
  13125.              return 0;
  13126.      mem_map[MAP_NR(page)] &= ~MAP_PAGE_RESERVED;
  13127. -    free_page_table(&ptrp[16*(dindex & (NUM_L2_ENTRIES-1))]);
  13128. +    free_page_table(ptrp);
  13129.      return 0;
  13130.  }
  13131.  
  13132. @@ -175,9 +175,10 @@
  13133.              krt[dindex >> 3] = VTOP(ptrp) | PAGE_TABLE;
  13134.      } else
  13135.          ptrp = (unsigned long *)PTOV(ptr & TABLE_MASK);
  13136. -    page = ptrp[16*(dindex & (NUM_L2_ENTRIES-1))];
  13137. +    ptrp += 16*(dindex & (NUM_L2_ENTRIES-1));
  13138. +    page = *ptrp;
  13139.      if (!page) {
  13140. -        page = (unsigned long)get_page_table (&ptrp[16*(dindex & (NUM_L2_ENTRIES-1))]);
  13141. +        page = (unsigned long)get_page_table (ptrp);
  13142.          if (!page)
  13143.              return -ENOMEM;
  13144.          else
  13145. @@ -240,7 +241,8 @@
  13146.      for (p = &vmlist ; (tmp = *p) ; p = &tmp->next) {
  13147.          if (tmp->addr == addr) {
  13148.              *p = tmp->next;
  13149. -            do_area(tmp->addr, tmp->size, free_area_pages);
  13150. +            do_area(tmp->addr, tmp->size - PAGE_SIZE,
  13151. +                free_area_pages);
  13152.              kfree(tmp);
  13153.              return;
  13154.          }
  13155. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/net/inet/dev.c linux-0.9pl4/net/inet/dev.c
  13156. --- linux-0.9pl3/net/inet/dev.c    Tue Sep 27 20:50:20 1994
  13157. +++ linux-0.9pl4/net/inet/dev.c    Mon Oct 10 16:48:34 1994
  13158. @@ -134,6 +134,7 @@
  13159.  
  13160.  struct packet_type *ptype_base = &ip_packet_type;
  13161.  static struct sk_buff *volatile backlog = NULL;
  13162. +static int backlog_size = 0;
  13163.  static unsigned long ip_bcast = 0;
  13164.  
  13165.  
  13166. @@ -482,13 +483,24 @@
  13167.  void
  13168.  netif_rx(struct sk_buff *skb)
  13169.  {
  13170. +  static int dropping = 0;
  13171.    /* Set any necessary flags. */
  13172.    skb->sk = NULL;
  13173.    skb->free = 1;
  13174.    
  13175. +  /* check that we aren't oevrdoing things.. */
  13176. +  if (!backlog_size)
  13177. +      dropping = 0;
  13178. +  else if (backlog_size > 100)
  13179. +      dropping = 1;
  13180. +  if (dropping) {
  13181. +    kfree_skb(skb, FREE_READ);
  13182. +    return;
  13183. +  }
  13184.    /* and add it to the "backlog" queue. */
  13185.    IS_SKB(skb);
  13186.    skb_queue_tail(&backlog,skb);
  13187. +  backlog_size++;
  13188.     
  13189.    /* If any packet arrived, mark it for processing. */
  13190.    if (backlog != NULL) mark_bh(INET_BH);
  13191. @@ -607,6 +619,7 @@
  13192.    /* Any data left to process? */
  13193.    while((skb=skb_dequeue(&backlog))!=NULL)
  13194.    {
  13195. +      backlog_size--;
  13196.        nitcount=dev_nit;
  13197.      flag=0;
  13198.      sti();
  13199. @@ -637,9 +650,6 @@
  13200.       * to anyone who wants it.
  13201.       */
  13202.      for (ptype = ptype_base; ptype != NULL; ptype = ptype->next) {
  13203. -        DPRINTF((DBG_DEV,
  13204. -            "INET: type is %x, comparing to %x\n", type,
  13205. -             ptype->type));
  13206.          if (ptype->type == type || ptype->type == NET16(ETH_P_ALL)) {
  13207.              struct sk_buff *skb2;
  13208.  
  13209. @@ -735,6 +745,9 @@
  13210.    memcpy_fromfs(&ifc, arg, sizeof(struct ifconf));
  13211.    len = ifc.ifc_len;
  13212.    pos = ifc.ifc_buf;
  13213. +  err=verify_area(VERIFY_WRITE, pos, len);
  13214. +  if(err)
  13215. +    return err;
  13216.  
  13217.    /* Loop over the interfaces, and write an info block for each. */
  13218.    for (dev = dev_base; dev != NULL; dev = dev->next) {
  13219. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/net/inet/eth.c linux-0.9pl4/net/inet/eth.c
  13220. --- linux-0.9pl3/net/inet/eth.c    Tue Sep 27 20:51:24 1994
  13221. +++ linux-0.9pl4/net/inet/eth.c    Mon Oct 10 16:48:34 1994
  13222. @@ -106,7 +106,6 @@
  13223.    /* Fill in the basic Ethernet MAC header. */
  13224.    eth = (struct ethhdr *) buff;
  13225.    eth->h_proto = htons(type);
  13226. -  DPRINTF((DBG_DEV, "ETH: eth->h_proto = %x)\n", eth->h_proto));
  13227.  
  13228.    /* We don't ARP for the LOOPBACK device... */
  13229.    if (dev->flags & IFF_LOOPBACK) {
  13230. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/net/inet/icmp.c linux-0.9pl4/net/inet/icmp.c
  13231. --- linux-0.9pl3/net/inet/icmp.c    Tue Mar  1 11:51:41 1994
  13232. +++ linux-0.9pl4/net/inet/icmp.c    Mon Oct 10 16:48:35 1994
  13233. @@ -285,6 +285,65 @@
  13234.  }
  13235.  
  13236.  
  13237. +/* Handle ICMP Timestamp requests. */
  13238. +static void
  13239. +icmp_timestamp(struct icmphdr *icmph, struct sk_buff *skb, struct device *dev,
  13240. +      unsigned long saddr, unsigned long daddr, int len,
  13241. +      struct options *opt)
  13242. +{
  13243. +  struct icmphdr *icmphr;
  13244. +  struct sk_buff *skb2;
  13245. +  int size, offset;
  13246. +  unsigned long *timeptr, midtime;
  13247. +  extern struct timeval xtime;            /* kernel/time.c */
  13248. +
  13249. +  size = sizeof(struct sk_buff) + dev->hard_header_len + 64 + len;
  13250. +  if (! (skb2 = alloc_skb(size, GFP_ATOMIC))) {
  13251. +    skb->sk = NULL;
  13252. +    kfree_skb(skb, FREE_READ);
  13253. +    return;
  13254. +  }
  13255. +  skb2->sk = NULL;
  13256. +  skb2->mem_addr = skb2;
  13257. +  skb2->mem_len = size;
  13258. +  skb2->free = 1;
  13259. +
  13260. +  /* Build Layer 2-3 headers for message back to source */
  13261. +  offset = ip_build_header(skb2, daddr, saddr, &dev, IPPROTO_ICMP, opt, len, 
  13262. +                skb->ip_hdr->tos, 255);
  13263. +  if (offset < 0) {
  13264. +    printk("ICMP: Could not build IP Header for ICMP TIMESTAMP Response\n");
  13265. +    kfree_skb(skb2, FREE_WRITE);
  13266. +    skb->sk = NULL;
  13267. +    kfree_skb(skb, FREE_READ);
  13268. +    return;
  13269. +  }
  13270. +
  13271. +  /* Re-adjust length according to actual IP header size. */
  13272. +  skb2->len = offset + len;
  13273. +
  13274. +  /* Build ICMP_TIMESTAMP Response message. */
  13275. +  icmphr = (struct icmphdr *) ((char *) (skb2 + 1) + offset);
  13276. +  memcpy((char *) icmphr, (char *) icmph, len);
  13277. +  icmphr->type = ICMP_TIMESTAMPREPLY;
  13278. +  icmphr->code = icmphr->checksum = 0;
  13279. +
  13280. +  /* fill in the current time as ms since midnight UT: */
  13281. +  midtime = (xtime.tv_sec % 86400) * 1000 + xtime.tv_usec / 1000;
  13282. +  timeptr = (unsigned long *) (icmphr + 1);
  13283. +  /* the originate timestamp (timeptr [0]) is still in the copy: */
  13284. +  timeptr [1] = timeptr [2] = htonl(midtime);
  13285. +
  13286. +  icmphr->checksum = ip_compute_csum((unsigned char *) icmphr, len);
  13287. +
  13288. +  /* Ship it out - free it when done */
  13289. +  ip_queue_xmit((struct sock *) NULL, dev, skb2, 1);
  13290. +
  13291. +  skb->sk = NULL;
  13292. +  kfree_skb(skb, FREE_READ);
  13293. +}
  13294. +
  13295. +
  13296.  /* Handle the ICMP INFORMATION REQUEST. */
  13297.  static void
  13298.  icmp_info(struct icmphdr *icmph, struct sk_buff *skb, struct device *dev,
  13299. @@ -397,6 +456,13 @@
  13300.          icmp_echo(icmph, skb1, dev, saddr, daddr, len, opt);
  13301.          return 0;
  13302.      case ICMP_ECHOREPLY:
  13303. +        skb1->sk = NULL;
  13304. +        kfree_skb(skb1, FREE_READ);
  13305. +        return(0);
  13306. +    case ICMP_TIMESTAMP:
  13307. +        icmp_timestamp(icmph, skb1, dev, saddr, daddr, len, opt);
  13308. +        return 0;
  13309. +    case ICMP_TIMESTAMPREPLY:
  13310.          skb1->sk = NULL;
  13311.          kfree_skb(skb1, FREE_READ);
  13312.          return(0);
  13313. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/net/inet/ip.c linux-0.9pl4/net/inet/ip.c
  13314. --- linux-0.9pl3/net/inet/ip.c    Mon Sep 26 19:24:28 1994
  13315. +++ linux-0.9pl4/net/inet/ip.c    Mon Oct 10 16:48:38 1994
  13316. @@ -10,6 +10,7 @@
  13317.   * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
  13318.   *        Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  13319.   *        Donald Becker, <becker@super.org>
  13320. + *        Alan Cox, <gw4pts@gw4pts.ampr.org>
  13321.   *
  13322.   * Fixes:
  13323.   *        Alan Cox    :    Commented a couple of minor bits of surplus code
  13324. @@ -40,6 +41,9 @@
  13325.   *        Alan Cox    :    Silly ip bug when an overlength
  13326.   *                    fragment turns up. Now frees the
  13327.   *                    queue.
  13328. + *        Linus Torvalds/ :    Memory leakage on fragmentation    
  13329. + *        Alan Cox    :    handling.
  13330. + *        Gerhard Koerting:    Forwarding uses IP priority hints
  13331.   *
  13332.   * To Fix:
  13333.   *        IP option processing is mostly not needed. ip_forward needs to know about routing rules
  13334. @@ -238,7 +242,7 @@
  13335.          return(-ENETUNREACH);
  13336.  
  13337.      *dev = rt->rt_dev;
  13338. -    if (saddr == 0x0100007FL && daddr != 0x0100007FL) 
  13339. +    if (saddr == htonl (0x7F000001L) && daddr != htonl (0x7F000001L)) 
  13340.          saddr = rt->rt_dev->pa_addr;
  13341.      raddr = rt->rt_gateway;
  13342.  
  13343. @@ -891,8 +895,7 @@
  13344.         offset = ntohs(iph->frag_off);
  13345.         flags = offset & ~IP_OFFSET;
  13346.         offset &= IP_OFFSET;
  13347. -       if (((flags & IP_MF) == 0) && (offset == 0)) 
  13348. -       {
  13349. +       if (((flags & IP_MF) == 0) && (offset == 0)) {
  13350.           if (qp != NULL) 
  13351.               ip_free(qp);    /* Huh? How could this exist?? */
  13352.           return(skb);
  13353. @@ -904,18 +907,18 @@
  13354.          * as we still are receiving fragments.  Otherwise, create a fresh
  13355.           * queue entry.
  13356.           */
  13357. -       if (qp != NULL) 
  13358. -       {
  13359. +    if (qp != NULL) {
  13360.           del_timer(&qp->timer);
  13361.           qp->timer.expires = IP_FRAG_TIME;    /* about 30 seconds    */
  13362.           qp->timer.data = (unsigned long) qp;    /* pointer to queue    */
  13363.           qp->timer.function = ip_expire;        /* expire function    */
  13364.           add_timer(&qp->timer);
  13365. +    } else {
  13366. +        if ((qp = ip_create(skb, iph, dev)) == NULL) {
  13367. +            skb->sk = NULL;
  13368. +            kfree_skb(skb, FREE_READ);
  13369. +            return NULL;
  13370.         } 
  13371. -       else 
  13372. -       {
  13373. -         if ((qp = ip_create(skb, iph, dev)) == NULL) 
  13374. -             return(NULL);
  13375.         }
  13376.   
  13377.         /* Determine the position of this fragment. */
  13378. @@ -984,6 +987,7 @@
  13379.               if (tfp->next != NULL) 
  13380.                   next->next->prev = next->prev;
  13381.               
  13382. +             kfree_skb(next->skb, FREE_READ);
  13383.               kfree_s(next, sizeof(struct ipfrag));
  13384.           }
  13385.           DPRINTF((DBG_IP, "IP: defrag: fixed high overlap %d bytes\n", i));
  13386. @@ -992,6 +996,11 @@
  13387.         /* Insert this fragment in the chain of fragments. */
  13388.         tfp = NULL;
  13389.         tfp = ip_frag_create(offset, end, skb, ptr);
  13390. +       if (!tfp) {
  13391. +           skb->sk = NULL;
  13392. +           kfree_skb(skb, FREE_READ);
  13393. +           return NULL;
  13394. +       }
  13395.         tfp->prev = prev;
  13396.         tfp->next = next;
  13397.         if (prev != NULL) 
  13398. @@ -1052,6 +1061,8 @@
  13399.           dev->name, dev->mtu, left, in_ntoa(iph->saddr)));
  13400.         DPRINTF((DBG_IP, " DST=%s\n", in_ntoa(iph->daddr)));
  13401.   
  13402. +    if (mtu < 8)
  13403. +        return;
  13404.         /* Check for any "DF" flag. */
  13405.         if (iph->frag_off & htons (IP_DF)) 
  13406.         {
  13407. @@ -1060,11 +1071,6 @@
  13408.               dev->name, dev->mtu, left, in_ntoa(iph->saddr)));
  13409.           DPRINTF((DBG_IP, " DST=%s\n", in_ntoa(iph->daddr)));
  13410.   
  13411. -         /*
  13412. -          * FIXME:
  13413. -          * We should send an ICMP warning message here!
  13414. -          */
  13415. -          
  13416.           icmp_send(skb,ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, dev); 
  13417.           return;
  13418.         }
  13419. @@ -1077,15 +1083,6 @@
  13420.         while(left > 0) 
  13421.         {
  13422.           len = left;
  13423. -#ifdef OLD         
  13424. -         if (len+8 > mtu) 
  13425. -             len = (dev->mtu - hlen - 8);
  13426. -         if ((left - len) >= 8) 
  13427. -         {
  13428. -             len /= 8;
  13429. -             len *= 8;
  13430. -         }
  13431. -#else
  13432.          /* IF: it doesn't fit, use 'mtu' - the data space left */
  13433.          if (len > mtu)
  13434.              len = mtu;
  13435. @@ -1096,7 +1093,6 @@
  13436.              len/=8;
  13437.              len*=8;
  13438.          }
  13439. -#endif                 
  13440.           DPRINTF((DBG_IP,"IP: frag: creating fragment of %d bytes (%d total)\n",
  13441.                               len, len + hlen));
  13442.   
  13443. @@ -1259,7 +1255,14 @@
  13444.          kfree_skb(skb2,FREE_WRITE);
  13445.      }
  13446.      else
  13447. +    {
  13448. +        if(iph->tos & IPTOS_LOWDELAY)
  13449. +            dev2->queue_xmit(skb2, dev2, SOPRI_INTERACTIVE);
  13450. +        else if(iph->tos & IPTOS_THROUGHPUT)
  13451. +            dev2->queue_xmit(skb2, dev2, SOPRI_BACKGROUND);
  13452. +        else
  13453.          dev2->queue_xmit(skb2, dev2, SOPRI_NORMAL);
  13454. +    }
  13455.    }
  13456.  }
  13457.  
  13458. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/net/inet/skbuff.c linux-0.9pl4/net/inet/skbuff.c
  13459. --- linux-0.9pl3/net/inet/skbuff.c    Thu Mar 10 14:15:09 1994
  13460. +++ linux-0.9pl4/net/inet/skbuff.c    Mon Oct 10 16:48:38 1994
  13461. @@ -426,12 +426,14 @@
  13462.  struct sk_buff *alloc_skb(unsigned int size,int priority)
  13463.  {
  13464.      struct sk_buff *skb;
  13465. -    extern unsigned long intr_count;
  13466.  
  13467.      if (intr_count && priority != GFP_ATOMIC) {
  13468. +        static int count = 0;
  13469. +        if (++count < 5) {
  13470.          printk("alloc_skb called nonatomically from interrupt %08lx\n",
  13471.              ((unsigned long *)&size)[-1]);
  13472.          priority = GFP_ATOMIC;
  13473. +        }
  13474.      }
  13475.      skb=(struct sk_buff *)kmalloc(size,priority);
  13476.      if(skb==NULL)
  13477. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/net/inet/sock.c linux-0.9pl4/net/inet/sock.c
  13478. --- linux-0.9pl3/net/inet/sock.c    Mon Sep 26 19:24:30 1994
  13479. +++ linux-0.9pl4/net/inet/sock.c    Mon Oct 10 16:48:40 1994
  13480. @@ -428,7 +428,7 @@
  13481.     * structure, otherwise we need to keep it around until
  13482.     * everything is gone.
  13483.     */
  13484. -      if (sk->rmem_alloc == 0 && sk->wmem_alloc == 0) 
  13485. +      if (sk->dead && sk->rmem_alloc == 0 && sk->wmem_alloc == 0) 
  13486.        {
  13487.          kfree_s((void *)sk,sizeof(*sk));
  13488.        } 
  13489. @@ -1194,8 +1194,12 @@
  13490.     * We need to free it up because the tcp module creates
  13491.     * it's own when it accepts one.
  13492.     */
  13493. -  if (newsock->data) kfree_s(newsock->data, sizeof(struct sock));
  13494. +  if (newsock->data) {
  13495. +      struct sock * sk = (struct sock *) newsock->data;
  13496.    newsock->data = NULL;
  13497. +      sk->dead = 1;
  13498. +      destroy_sock(sk);
  13499. +  }
  13500.  
  13501.    if (sk1->prot->accept == NULL) return(-EOPNOTSUPP);
  13502.  
  13503. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/net/inet/tcp.c linux-0.9pl4/net/inet/tcp.c
  13504. --- linux-0.9pl3/net/inet/tcp.c    Mon Sep 26 19:24:33 1994
  13505. +++ linux-0.9pl4/net/inet/tcp.c    Mon Oct 10 16:48:43 1994
  13506. @@ -12,6 +12,9 @@
  13507.   *        Mark Evans, <evansmp@uhura.aston.ac.uk>
  13508.   *        Corey Minyard <wf-rch!minyard@relay.EU.net>
  13509.   *        Florian La Roche, <flla@stud.uni-sb.de>
  13510. + *        Charles Hedrick, <hedrick@klinzhai.rutgers.edu>
  13511. + *        Linus Torvalds, <torvalds@cs.helsinki.fi>
  13512. + *        Alan Cox, <gw4pts@gw4pts.ampr.org>
  13513.   *
  13514.   * Fixes:    
  13515.   *        Alan Cox    :    Numerous verify_area() calls
  13516. @@ -63,6 +66,7 @@
  13517.   *        Charles Hedrick    :    Window fix
  13518.   *        Linus        :    Rewrote tcp_read() and URG handling
  13519.   *                    completely
  13520. + *        Gerhard Koerting:    Fixed some missing timer handling
  13521.   *
  13522.   *
  13523.   * To Fix:
  13524. @@ -1548,8 +1552,13 @@
  13525.                 IPPROTO_TCP, sk->opt,
  13526.                 sizeof(struct tcphdr),sk->ip_tos,sk->ip_ttl);
  13527.    if (tmp < 0) {
  13528. +      /* Finish anyway, treat this as a send that got lost. */
  13529.        buff->free=1;
  13530.      prot->wfree(sk,buff->mem_addr, buff->mem_len);
  13531. +    if(sk->state==TCP_ESTABLISHED)
  13532. +        sk->state=TCP_FIN_WAIT1;
  13533. +    else
  13534. +        sk->state=TCP_FIN_WAIT2;
  13535.      release_sock(sk);
  13536.      DPRINTF((DBG_TCP, "Unable to build header for fin.\n"));
  13537.      return;
  13538. @@ -2085,6 +2094,13 @@
  13539.                           sizeof(struct tcphdr),sk->ip_tos,sk->ip_ttl);
  13540.          if (tmp < 0) {
  13541.              kfree_skb(buff,FREE_WRITE);
  13542. +            if(sk->state==TCP_ESTABLISHED)
  13543. +                sk->state=TCP_FIN_WAIT1;
  13544. +            else
  13545. +                sk->state=TCP_FIN_WAIT2;
  13546. +            reset_timer(sk, TIME_CLOSE,4*sk->rto);
  13547. +            if(timeout)
  13548. +                tcp_time_wait(sk);
  13549.              DPRINTF((DBG_TCP, "Unable to build header for fin.\n"));
  13550.              release_sock(sk);
  13551.              return;
  13552. @@ -2915,6 +2931,7 @@
  13553.      case TCP_SYN_SENT:
  13554.      case TCP_ESTABLISHED:
  13555.          /* Contains the one that needs to be acked */
  13556. +        reset_timer(sk, TIME_CLOSE, TCP_TIMEOUT_LEN);
  13557.          sk->fin_seq = th->seq+1;
  13558.          sk->state = TCP_CLOSE_WAIT;
  13559.          if (th->rst) sk->shutdown = SHUTDOWN_MASK;
  13560. @@ -3447,6 +3464,15 @@
  13561.          kfree_skb(skb, FREE_READ);
  13562.          release_sock(sk);
  13563.          return(0);
  13564. +
  13565. +    case TCP_SYN_RECV:
  13566. +        if (th->syn) {
  13567. +            /* Probably a retransmitted syn */
  13568. +            kfree_skb(skb, FREE_READ);
  13569. +            release_sock(sk);
  13570. +            return(0);
  13571. +        }
  13572. +
  13573.  
  13574.      default:
  13575.          if (!tcp_sequence(sk, th, len, opt, saddr,dev)) {
  13576. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/tools/amiga/bootstrap.c linux-0.9pl4/tools/amiga/bootstrap.c
  13577. --- linux-0.9pl3/tools/amiga/bootstrap.c    Thu Sep 29 18:19:15 1994
  13578. +++ linux-0.9pl4/tools/amiga/bootstrap.c    Mon Nov 21 18:09:09 1994
  13579. @@ -2,12 +2,12 @@
  13580.  ** bootstrap.c -- This program loads the Linux/68k kernel into an Amiga
  13581.  **                and and launches it.
  13582.  **
  13583. -** Copyright 1993 by Hamish Macdonald, Greg Harp
  13584. +** Copyright 1993,1994 by Hamish Macdonald, Greg Harp
  13585.  **
  13586.  ** Modified 11-May-94 by Geert Uytterhoeven (uytterho@cs.kuleuven.ac.be)
  13587.  **     - A3640 MapROM check
  13588.  ** Modified 31-May-94 by Geert Uytterhoeven
  13589. -**     - Memory thrash problem solved
  13590. +**     - Memory trash problem solved
  13591.  **
  13592.  ** This file is subject to the terms and conditions of the GNU General Public
  13593.  ** License.  See the file README.legal in the main directory of this archive
  13594. @@ -48,6 +48,7 @@
  13595.  struct GfxBase *GfxBase;
  13596.  
  13597.  struct bootinfo bi;
  13598. +u_long bi_size = sizeof bi;
  13599.  
  13600.  caddr_t CustomBase = (caddr_t)CUSTOM_PHYSADDR;
  13601.  
  13602. @@ -78,6 +79,7 @@
  13603.      movel    _start_mem,a5
  13604.      movel    _mem_size,d0
  13605.      movel    _rd_size,d1
  13606. +    movel    _bi_size,d5
  13607.      movel    a3@(4),d2    | kexec.a_text
  13608.      movel    a3@(8),d3    | kexec.a_data
  13609.      movel    a3@(12),d4    | kexec.a_bss
  13610. @@ -104,12 +106,23 @@
  13611.      bras    1b
  13612.  2:
  13613.  
  13614. +                | /* copy bootinfo to end of bss */
  13615. +    movel    a4,a1        | src = (u long *)memptr + kexec.a_text + kexec.a_data);
  13616. +    addl    d2,a1
  13617. +    addl    d3,a1        | dest = end of bss (already in a0)
  13618. +    movel   d5,d7        | count = sizeof bi
  13619. +    subql    #1,d7
  13620. +1:    moveb    a1@+,a0@+    | while (--count > -1)
  13621. +    dbra    d7,1b        |    *dest++ = *src++
  13622. +    
  13623. +
  13624.                  | /* copy the ramdisk to the top of memory (from back to front) */
  13625.      movel    a5,a1        | dest = (u_long *)(start_mem + mem_size);
  13626.      addl    d0,a1
  13627. -    movel    a4,a2        | limit = (u_long *)(memptr + kexec.a_text + kexec.a_data);
  13628. +    movel    a4,a2        | limit = (u_long *)(memptr + kexec.a_text + kexec.a_data + sizeof bi);
  13629.      addl    d2,a2
  13630.      addl    d3,a2
  13631. +        addl    d5,a2
  13632.      movel    a2,a0        | src = (u_long *)((u_long)limit + rd_size);
  13633.      addl    d1,a0
  13634.  1:    cmpl    a0,a2
  13635. @@ -155,6 +168,7 @@
  13636.      movel    d7,d0
  13637.      notl    d0
  13638.      movel    d0,a0@
  13639. +    nop
  13640.      cmpl    a1@,d0
  13641.      jnes    1f
  13642.  /* MapROMmed A3640 present */
  13643. @@ -189,13 +203,12 @@
  13644.      char *ramdisk_name = NULL;
  13645.      char *memfile = NULL;
  13646.      u_long memreq;
  13647. -    struct nlist *nl;
  13648.      void (*startfunc)(void);
  13649.      long startcodesize;
  13650. -    u_long *stack, kbi_offset;
  13651. +    u_long *stack, text_offset;
  13652.  
  13653.      /* print the greet message */
  13654. -    puts(" Linux/68k Amiga Bootstrap version 1.9");
  13655. +    puts(" Linux/68k Amiga Bootstrap version 1.10");
  13656.      puts("Copyright 1993,1994 by Hamish Macdonald and Greg Harp\n");
  13657.  
  13658.      /* machine is Amiga */
  13659. @@ -526,6 +539,27 @@
  13660.          exit (EXIT_FAILURE);
  13661.      }
  13662.  
  13663. +    switch (N_MAGIC(kexec)) {
  13664. +      case ZMAGIC:
  13665. +        text_offset = N_TXTOFF(kexec);
  13666. +        break;
  13667. +      case QMAGIC:
  13668. +        text_offset = sizeof(kexec);
  13669. +        /* the text size includes the exec header; remove this */
  13670. +        kexec.a_text -= sizeof(kexec);
  13671. +        break;
  13672. +      default:
  13673. +        fprintf (stderr, "Wrong magic number %lo in kernel header\n",
  13674. +             N_MAGIC(kexec));
  13675. +        exit (EXIT_FAILURE);
  13676. +    }
  13677. +
  13678. +    /* Load the kernel at one page after start of mem */
  13679. +    start_mem += PAGE_SIZE;
  13680. +    mem_size -= PAGE_SIZE;
  13681. +    /* Align bss size to multiple of four */
  13682. +    kexec.a_bss = (kexec.a_bss + 3) & ~3;
  13683. +
  13684.      if (ramdisk_name) {
  13685.          if ((rfd = open (ramdisk_name, O_RDONLY)) == -1) {
  13686.              fprintf (stderr, "Unable to open ramdisk file %s\n",
  13687. @@ -540,22 +574,13 @@
  13688.      rd_size = bi.ramdisk_size << 10;
  13689.      bi.ramdisk_addr = (u_long)start_mem + mem_size - rd_size;
  13690.  
  13691. -    /* find offset to boot_info structure */
  13692. -    if (!(nl = get_nlist (kernel_name, "_boot_info"))) {
  13693. -        perror ("get_nlist");
  13694. -        exit (EXIT_FAILURE);
  13695. -    } else {
  13696. -        kbi_offset = nl->n_value - kexec.a_entry;
  13697. -        free (nl);
  13698. -    }
  13699. -
  13700. -    memreq = kexec.a_text + kexec.a_data + rd_size;
  13701. +    memreq = kexec.a_text + kexec.a_data + sizeof(bi) + rd_size;
  13702.      if (!(memptr = (char *)AllocMem (memreq, MEMF_FAST | MEMF_CLEAR))) {
  13703.          fprintf (stderr, "Unable to allocate memory\n");
  13704.          exit (EXIT_FAILURE);
  13705.      }
  13706.  
  13707. -    if (lseek (kfd, N_TXTOFF(kexec), L_SET) == -1) {
  13708. +    if (lseek (kfd, text_offset, L_SET) == -1) {
  13709.          fprintf (stderr, "Failed to seek to text\n");
  13710.          FreeMem ((void *)memptr, memreq);
  13711.          exit (EXIT_FAILURE);
  13712. @@ -565,11 +590,8 @@
  13713.          FreeMem ((void *)memptr, memreq);
  13714.          exit (EXIT_FAILURE);
  13715.      }
  13716. -    if (lseek (kfd, N_DATOFF(kexec), L_SET) == -1) {
  13717. -        fprintf (stderr, "Failed to seek to data\n");
  13718. -        FreeMem ((void *)memptr, memreq);
  13719. -        exit (EXIT_FAILURE);
  13720. -    }
  13721. +
  13722. +    /* data follows immediately after text */
  13723.      if (read (kfd, memptr + kexec.a_text, kexec.a_data) != kexec.a_data) {
  13724.          fprintf (stderr, "Failed to read data\n");
  13725.          FreeMem ((void *)memptr, memreq);
  13726. @@ -577,8 +599,9 @@
  13727.      }
  13728.      close (kfd);
  13729.  
  13730. -    /* copy the boot_info struct to the kernel image */
  13731. -    memcpy ((void *)(memptr + kbi_offset), &bi, sizeof(bi));
  13732. +    /* copy the boot_info struct to the end of the kernel image */
  13733. +    memcpy ((void *)(memptr + kexec.a_text + kexec.a_data), &bi,
  13734. +        sizeof(bi));
  13735.  
  13736.      if (rfd != -1) {
  13737.          if (lseek (rfd, 0, L_SET) == -1) {
  13738. @@ -586,8 +609,8 @@
  13739.              FreeMem ((void *)memptr, memreq);
  13740.              exit (EXIT_FAILURE);
  13741.          }
  13742. -        if (read (rfd, memptr + kexec.a_text + kexec.a_data,
  13743. -              rd_size) != rd_size) {
  13744. +        if (read (rfd, memptr + kexec.a_text + kexec.a_data 
  13745. +              + sizeof(bi), rd_size) != rd_size) {
  13746.              fprintf (stderr, "Failed to read ramdisk file\n");
  13747.              FreeMem ((void *)memptr, memreq);
  13748.              exit (EXIT_FAILURE);
  13749. @@ -622,12 +645,15 @@
  13750.                  (u_long)memptr + kexec.a_text + kexec.a_data,
  13751.                  bi.ramdisk_size);
  13752.  
  13753. -        printf ("\nKernel text at %#lx, code size %d\n",
  13754. -            start_mem + N_TXTADDR(kexec), kexec.a_text);
  13755. -        printf ("Kernel data at %#lx, data size %d\n",
  13756. -            start_mem + N_DATADDR(kexec), kexec.a_data );
  13757. -        printf ("Kernel bss  at %#lx, bss  size %d\n",
  13758. -            start_mem + N_BSSADDR(kexec), kexec.a_bss );
  13759. +        printf ("\nKernel text at %#lx, code size %x\n",
  13760. +            start_mem, kexec.a_text);
  13761. +        printf ("Kernel data at %#lx, data size %x\n",
  13762. +            start_mem + kexec.a_text, kexec.a_data );
  13763. +        printf ("Kernel bss  at %#lx, bss  size %x\n",
  13764. +            start_mem + kexec.a_text + kexec.a_data,
  13765. +            kexec.a_bss );
  13766. +        printf ("boot info at %#lx\n", start_mem + kexec.a_text
  13767. +            + kexec.a_data + kexec.a_bss);
  13768.  
  13769.          printf ("\nKernel entry is %#x\n", kexec.a_entry );
  13770.  
  13771. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/tools/amiga/bootstrap.h linux-0.9pl4/tools/amiga/bootstrap.h
  13772. --- linux-0.9pl3/tools/amiga/bootstrap.h    Sun Aug 14 10:29:11 1994
  13773. +++ linux-0.9pl4/tools/amiga/bootstrap.h    Sat Nov 12 12:40:13 1994
  13774. @@ -128,12 +128,6 @@
  13775.   */
  13776.  #define GFXG_AGA    (GFXF_AA_ALICE|GFXF_AA_LISA)
  13777.  
  13778. -/*
  13779. - * Get an nlist structure containing the information
  13780. - * for the given symbol from the given file.
  13781. - */
  13782. -extern struct nlist *get_nlist (const char *fname, const char *symname);
  13783. -
  13784.  struct Library;
  13785.  
  13786.  extern struct ExecBase *SysBase;
  13787. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/tools/amiga/get_nlist.c linux-0.9pl4/tools/amiga/get_nlist.c
  13788. --- linux-0.9pl3/tools/amiga/get_nlist.c    Sun Aug 14 10:29:11 1994
  13789. +++ linux-0.9pl4/tools/amiga/get_nlist.c    Wed Dec 31 19:00:00 1969
  13790. @@ -1,97 +0,0 @@
  13791. -/*
  13792. -** get_nlist.c -- This file contains the routines for getting a symbol
  13793. -**          table entry when booting the Amiga Linux kernel.
  13794. -**
  13795. -** Copyright 1993 by Hamish Macdonald
  13796. -**
  13797. -** This file is subject to the terms and conditions of the GNU General Public
  13798. -** License.  See the file README.legal in the main directory of this archive
  13799. -** for more details.
  13800. -**
  13801. -*/
  13802. -
  13803. -
  13804. -#include <stdlib.h>
  13805. -#include <stdio.h>
  13806. -#include <sys/fcntl.h>
  13807. -#include <unistd.h>
  13808. -#include <linux/a.out.h>
  13809. -
  13810. -struct nlist *get_nlist (const char *fname, const char *symname)
  13811. -{
  13812. -    int fd = open (fname, O_RDONLY);
  13813. -    struct exec ex;
  13814. -    struct nlist *nl, *p = NULL, *syms;
  13815. -    char *strs;
  13816. -    off_t filesize;
  13817. -    long strsize, numsyms;
  13818. -
  13819. -    if (fd == -1)
  13820. -    return NULL;
  13821. -
  13822. -#ifdef DEBUG
  13823. -    printf ("fd is %d\n", fd);
  13824. -#endif
  13825. -
  13826. -    read (fd, &ex, sizeof(ex));
  13827. -    if (!ex.a_syms) {
  13828. -    close (fd);
  13829. -    return NULL;
  13830. -    }
  13831. -
  13832. -#ifdef DEBUG
  13833. -    printf ("%d bytes of symbol data\n", ex.a_syms);
  13834. -#endif
  13835. -
  13836. -    syms = (struct nlist *)malloc (ex.a_syms);
  13837. -    if (!syms) {
  13838. -    close (fd);
  13839. -    return NULL;
  13840. -    }
  13841. -    lseek (fd, N_SYMOFF(ex), L_SET);
  13842. -    read (fd, syms, ex.a_syms);
  13843. -    numsyms = ex.a_syms / sizeof (struct nlist);
  13844. -#ifdef DEBUG
  13845. -    printf ("there are %d symbols\n", numsyms);
  13846. -#endif
  13847. -
  13848. -    filesize = lseek (fd, 0L, L_XTND);
  13849. -#ifdef DEBUG
  13850. -    printf ("there are %d characters in the file\n", filesize);
  13851. -#endif
  13852. -    strsize = filesize - N_STROFF(ex);
  13853. -#ifdef DEBUG
  13854. -    printf ("%d characters in the string table\n", strsize);
  13855. -#endif
  13856. -
  13857. -    strs = (char *)malloc (strsize);
  13858. -    if (!strs) {
  13859. -    free (syms);
  13860. -    close (fd);
  13861. -    return NULL;
  13862. -    }
  13863. -    lseek (fd, N_STROFF(ex), L_SET);
  13864. -    read (fd, strs, strsize);
  13865. -
  13866. -    for (nl = syms; nl < syms + numsyms; nl++) {
  13867. -#ifdef DEBUG
  13868. -    printf ("checking symbol number %d, name %s\n",
  13869. -        nl - syms, strs + nl->n_un.n_strx);
  13870. -#endif
  13871. -    if (strcmp (symname, strs + nl->n_un.n_strx) == 0
  13872. -        && nl->n_type == N_BSS | N_EXT) {
  13873. -        p = (struct nlist *)malloc (sizeof (struct nlist)
  13874. -                    + strlen(strs + nl->n_un.n_strx) + 1);
  13875. -        if (!p)
  13876. -        break;
  13877. -        *p = *nl;
  13878. -        p->n_un.n_name = (char *)(p+1);
  13879. -        strcpy (p->n_un.n_name, strs + nl->n_un.n_strx);
  13880. -    }
  13881. -    }
  13882. -
  13883. -    free (strs);
  13884. -    free (syms);
  13885. -    close (fd);
  13886. -    return p;
  13887. -}
  13888. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/tools/atari/Makefile linux-0.9pl4/tools/atari/Makefile
  13889. --- linux-0.9pl3/tools/atari/Makefile    Sun Aug 14 10:29:12 1994
  13890. +++ linux-0.9pl4/tools/atari/Makefile    Thu Nov 24 21:11:00 1994
  13891. @@ -3,19 +3,10 @@
  13892.  CFLAGS    := -Wall -O2 -fno-defer-pop -mint -s
  13893.  LD        := d:/gnu/bin/gcc.ttp
  13894.  LDFLAGS    := -mint -D__GNUC__
  13895. -AS        := d:/gnu/bin/gcc.ttp -c
  13896.  
  13897. -bootstra.ttp: boot_asm.o bootstra.o
  13898. +bootstra.ttp: bootstra.o
  13899.      $(LD) $(LDFLAGS) -o $@ $^
  13900.      prgflags 7 7 $@
  13901.      cp $@ d:/linux
  13902.  
  13903.  bootstra.o: bootstra.c bootinfo.h
  13904. -
  13905. -gen_nlis.o: gen_nlis.c
  13906. -
  13907. -boot_asm.o: boot_asm.S
  13908. -
  13909. -%.s: %.c
  13910. -    $(CC) $(CFLAGS) -S $^ -o $@
  13911. -
  13912. diff -ubr -x RCS -x *.[ao] -x .depend -x .version -x .config -x System.map -x vmlinux -x bootstrap -x *~ -x config.old -x *.orig -x *.rej -x *# -x version.h -x autoconf.h --new-file linux-0.9pl3/tools/atari/bootstrap.c linux-0.9pl4/tools/atari/bootstrap.c
  13913. --- linux-0.9pl3/tools/atari/bootstrap.c    Sun Aug 14 10:29:12 1994
  13914. +++ linux-0.9pl4/tools/atari/bootstrap.c    Mon Nov 21 18:12:14 1994
  13915. @@ -8,6 +8,15 @@
  13916.  ** for more details.
  13917.  **
  13918.  ** History:
  13919. +**      14 Nov 1994 YANML (Yet Another New Memory Layout :-) kernel
  13920. +**            start address is KSTART_ADDR + PAGE_SIZE, this
  13921. +**            does not need the ugly klugde with
  13922. +**            -fwritable-strings (++andreas)
  13923. +**      09 Sep 1994 Adapted to the new memory layout: All the boot_info entry
  13924. +**                  mentions all ST-Ram and the mover is located somewhere
  13925. +**                  in the middle of memory (roman)
  13926. +**                  Added the default arguments file known from the other
  13927. +**                  bootstrap version
  13928.  **      19 Feb 1994 Changed everything so that it works? (rdv)
  13929.  **      14 Mar 1994 New mini-copy routine used (rdv)
  13930.  */
  13931. @@ -17,6 +26,7 @@
  13932.  #include <unistd.h>
  13933.  #include <stddef.h>
  13934.  #include <string.h>
  13935. +#include <ctype.h>
  13936.  #include "sysvars.h"
  13937.  #include <osbind.h>
  13938.  #include <sys/types.h>
  13939. @@ -34,7 +44,9 @@
  13940.  
  13941.  extern char *optarg;
  13942.  extern int optind;
  13943. -extern struct nlist *get_nlist(const char *fname, const char *symname);
  13944. +static void get_default_args( int *argc, char ***argv );
  13945. +/* This is missing in <unistd.h> */
  13946. +extern int sync (void);
  13947.  
  13948.  struct bootinfo bi;
  13949.  u_long *cookiejar;
  13950. @@ -92,50 +104,79 @@
  13951.      subql    #4,d0
  13952.      jcc    1b
  13953.  
  13954. +    tstl    d1
  13955. +    beq        3f
  13956. +
  13957.  2:    movel    a3@-,a2@-       /* copy the ramdisk starting at the end */
  13958.      subql    #4,d1
  13959.      jcc    2b
  13960.  
  13961. -    jmp    a4@             /* jump to the start of the kernel */
  13962. +3:    jmp    a4@             /* jump to the start of the kernel */
  13963.  _copyallend:
  13964.  ");
  13965.  
  13966.  extern char copyall, copyallend;
  13967.  
  13968. -static void volatile boot_exit(int status)
  13969. +/* ++andreas: this must be inline due to Super */
  13970. +static inline void boot_exit (int) __attribute__ ((noreturn));
  13971. +static inline void boot_exit(int status)
  13972.  {
  13973.      /* first go back to user mode */
  13974.      (void)Super(userstk);
  13975. +    getchar();
  13976.      exit(status);
  13977.  }
  13978.  
  13979.  int main(int argc, char *argv[])
  13980.  {
  13981. -    int debugflag = 0, ch, kfd, rfd = -1, lang, i;
  13982. +    int debugflag = 0, ch, kfd, rfd = -1, i, ignore_ttram = 0;
  13983. +    int load_to_stram = 0;
  13984. +#if 0
  13985. +    int lang;
  13986. +#endif
  13987.      char *ramdisk_name, *kernel_name, *memptr;
  13988.      u_long ST_ramsize, TT_ramsize, memreq;
  13989. -    u_long cpu_type, fpu_type, mch_type, mint, language;
  13990. -    struct nlist *nl;
  13991. +    u_long cpu_type, fpu_type, mch_type, mint;
  13992. +#if 0
  13993. +    u_long language;
  13994. +#endif
  13995.      struct exec kexec;
  13996. +#if 0
  13997.      OSHEADER *os_header;
  13998. -    u_long start_mem, mem_size, rd_size, kbi_offset;
  13999. +#endif
  14000. +    u_long start_mem, mem_size, rd_size, text_offset;
  14001. +#if 0
  14002. +    u_long mover_size;
  14003. +    void   *mover_addr;
  14004. +#endif
  14005.  
  14006.      ramdisk_name = NULL;
  14007.      kernel_name = "vmlinux";
  14008.  
  14009.      /* print the startup message */
  14010. -    puts("\fLinux/68k Atari Bootstrap version 0.2");
  14011. -    puts("Copyright 1993,1994 by Arjan Knor, Robert de Vries\n");
  14012. +    puts("\fLinux/68k Atari Bootstrap version 0.4");
  14013. +    puts("Copyright 1993,1994 by Arjan Knor, Robert de Vries, Roman Hodek, Andreas Schwab\n");
  14014. +
  14015. +    /* ++roman: If no arguments on the command line, read them from
  14016. +     * file */
  14017. +    if (argc == 1)
  14018. +        get_default_args( &argc, &argv );
  14019.  
  14020.      /* machine is Atari */
  14021.      bi.machtype = MACH_ATARI;
  14022.  
  14023.      /* check arguments */
  14024. -    while ((ch = getopt(argc, argv, "dk:r:")) != EOF)
  14025. +    while ((ch = getopt(argc, argv, "dtsk:r:")) != EOF)
  14026.      switch (ch) {
  14027.        case 'd':
  14028.          debugflag = 1;
  14029.          break;
  14030. +      case 't':
  14031. +        ignore_ttram = 1;
  14032. +        break;
  14033. +      case 's':
  14034. +        load_to_stram = 1;
  14035. +        break;
  14036.        case 'k':
  14037.          kernel_name = optarg;
  14038.          break;
  14039. @@ -264,7 +305,8 @@
  14040.      /* The size must be a multiple of 1MB. */
  14041.      i = 0;
  14042.      TT_ramsize = 0;
  14043. -    if (mch_type == MACH_TT && *ramtop) {
  14044. +    if (!ignore_ttram &&
  14045. +        (mch_type == MACH_TT || mch_type == MACH_FALCON) && *ramtop) {
  14046.      /* the 'ramtop' variable at 0x05a4 is not
  14047.       * officially documented. We use it anyway
  14048.       * because it is the only way to get the TTram size.
  14049. @@ -277,28 +319,31 @@
  14050.  
  14051.      printf("TT-RAM: %ld Mb; ", TT_ramsize);
  14052.      }
  14053. -
  14054. -    bi.memory[i].addr = PAGE_SIZE; /* do not use the exception space
  14055. -                   (this comes down to the first page) */
  14056. -    bi.memory[i].size = (*phystop - bi.memory[i].addr) & ~(MB - 1);
  14057. +    bi.memory[i].addr = 0;
  14058. +    bi.memory[i].size = *phystop & ~(MB - 1);
  14059.      ST_ramsize = bi.memory[i].size / MB;
  14060.  
  14061. -    bi.bi_atari.stram_start = bi.memory[i].addr + bi.memory[i].size;
  14062. -    bi.bi_atari.stram_size = *phystop - bi.bi_atari.stram_start;
  14063. -
  14064.      i++;
  14065.  
  14066. -    printf("ST-RAM: %ld Mb; %ld Kb unmapped; ", ST_ramsize,
  14067. -       bi.bi_atari.stram_size / 1024);
  14068. +    printf("ST-RAM: %ld Mb; ", ST_ramsize );
  14069.  
  14070.      bi.num_memory = i;
  14071.  
  14072. +    if (load_to_stram && i > 1)
  14073. +      {
  14074. +    /* Put ST-RAM first in the list of mem blocks */
  14075. +    struct mem_info temp = bi.memory[i - 1];
  14076. +    bi.memory[i - 1] = bi.memory[0];
  14077. +    bi.memory[0] = temp;
  14078. +      }
  14079. +
  14080.      /* verify that there is enough RAM; ST- and TT-RAM combined */
  14081.      if (ST_ramsize + TT_ramsize < MIN_RAMSIZE) {
  14082.      puts("Not enough RAM. Aborting...");
  14083.      boot_exit(10);
  14084.      }
  14085.  
  14086. +#if 0    
  14087.      /* Get language/keyboard info */
  14088.      /* TODO: do we need this ? */
  14089.      /* Could be used to auto-select keyboard map later on. (rdv) */
  14090. @@ -354,6 +399,7 @@
  14091.      }
  14092.      printf("\n");
  14093.      }
  14094. +#endif
  14095.  
  14096.      /*
  14097.       * Copy command line options into the kernel command line.
  14098. @@ -394,6 +440,27 @@
  14099.      boot_exit (EXIT_FAILURE);
  14100.      }
  14101.  
  14102. +    switch (N_MAGIC(kexec)) {
  14103. +    case ZMAGIC:
  14104. +    text_offset = N_TXTOFF(kexec);
  14105. +    break;
  14106. +    case QMAGIC:
  14107. +    text_offset = sizeof(kexec);
  14108. +    /* the text size includes the exec header; remove this */
  14109. +    kexec.a_text -= sizeof(kexec);
  14110. +    break;
  14111. +    default:
  14112. +    fprintf (stderr, "Wrong magic number %lo in kernel header\n",
  14113. +         N_MAGIC(kexec));
  14114. +    boot_exit (EXIT_FAILURE);
  14115. +    }
  14116. +
  14117. +    /* Load the kernel one page after start of mem */
  14118. +    start_mem += PAGE_SIZE;
  14119. +    mem_size -= PAGE_SIZE;
  14120. +    /* Align bss size to multiple of four */
  14121. +    kexec.a_bss = (kexec.a_bss + 3) & ~3;
  14122. +
  14123.      /* init ramdisk */
  14124.      if(ramdisk_name) {
  14125.      if((rfd = open(ramdisk_name, O_RDONLY)) == -1) {
  14126. @@ -409,23 +476,55 @@
  14127.      rd_size = bi.ramdisk_size << 10;
  14128.      bi.ramdisk_addr = (u_long)start_mem + mem_size - rd_size;
  14129.  
  14130. -    /* find offset to boot_info structure */
  14131. -    if (!(nl = get_nlist (kernel_name, "_boot_info")))
  14132. -    {
  14133. -    perror ("get_nlist");
  14134. -    boot_exit (EXIT_FAILURE);
  14135. -    }
  14136. +    /* calculate the total required amount of memory */
  14137. +    memreq = kexec.a_text + kexec.a_data + kexec.a_bss + sizeof (bi) + rd_size;
  14138.  
  14139. -    kbi_offset = nl->n_value - kexec.a_entry;
  14140. -    free (nl);
  14141. +    /* ++andreas: This not needed any more, left in for reference :-) */
  14142. +#if 0
  14143.  
  14144. -    /* calculate the total required amount of memory */
  14145. -    memreq = kexec.a_text + kexec.a_data + kexec.a_bss + rd_size;
  14146. +    /* Allocate memory for the mover routine. It has to be disjunct
  14147. +     * from all three other areas, the kernel destination, the ramdisk
  14148. +     * destination and the load buffer for both. Because the mover
  14149. +     * space is allocated separately from the load buffer, it cannot
  14150. +     * overlap that one.
  14151. +     * To get some appropriate memory for the mover, the following
  14152. +     * steps are tried:
  14153. +     *  - Leave it where it is (in bootstrap's code space)
  14154. +     *  - If the kernel will go into TT-Ram, allocate memory from the ST-Ram
  14155. +     *  - Allocate some memory before allocating the load buffer.
  14156. +     *  - Allocate some memory after the load buffer
  14157. +     *  - If all that failed, it is unlikely to find a suitable place.
  14158. +     *    But to be sure, memory is alloced in bigger steps (32K)
  14159. +     *    until there is no memory left.
  14160. +     */
  14161. +#define    IS_DISJUNCT(a1,s1,a2,s2) ( (a2) > (a1)+(s1) || (a2)+(s2) < (a1) )
  14162. +#define MOVER_DISJUNCT(addr)                                        \
  14163. +    (IS_DISJUNCT( start_mem, kexec.a_text+kexec.a_data+kexec.a_bss,    \
  14164. +                  (unsigned long)(addr), mover_size ) &&            \
  14165. +     IS_DISJUNCT( start_mem + mem_size - rd_size, rd_size,            \
  14166. +                  (unsigned long)(addr), mover_size ))
  14167. +    
  14168. +    mover_size = ©allend - ©all;
  14169. +    mover_addr = ©all;
  14170. +
  14171. +    if (!MOVER_DISJUNCT(mover_addr) && TT_ramsize) {
  14172. +        /* If there is TT-Ram, try to put the mover into ST-Ram */
  14173. +        unsigned long addr;
  14174. +        addr = Mxalloc( mover_size, 0 );
  14175. +        if ((signed long)addr > 0) mover_addr = addr;
  14176. +    }
  14177. +    if (!MOVER_DISJUNCT(mover_addr)) {
  14178. +         if (!(mover_addr = (void *)Malloc( mover_size ))) {
  14179. +            fprintf( stderr, "Unable to allocate memory for mover code\n" );
  14180. +            boot_exit( EXIT_FAILURE );
  14181. +        }
  14182. +    }
  14183. +#endif
  14184.   
  14185.      /* allocate RAM for the kernel */
  14186.      if (!(memptr = (char *)Malloc (memreq)))
  14187.      {
  14188. -    fprintf (stderr, "Unable to allocate memory\n");
  14189. +    fprintf (stderr, "Unable to allocate memory for kernel and ramdisk\n");
  14190.      boot_exit (EXIT_FAILURE);
  14191.      }
  14192.      else
  14193. @@ -433,8 +532,18 @@
  14194.  
  14195.      (void)memset(memptr, 0, memreq);
  14196.  
  14197. +#if 0
  14198. +    while( !MOVER_DISJUNCT(mover_addr) ) {
  14199. +         if (!(mover_addr = (void *)Malloc( mover_size ))) {
  14200. +            fprintf( stderr, "Unable to allocate memory for mover code\n" );
  14201. +            boot_exit( EXIT_FAILURE );
  14202. +        }
  14203. +        (void)Malloc( 32*1024 );
  14204. +    }
  14205. +#endif
  14206. +    
  14207.      /* read the text and data segments from the kernel image */
  14208. -    if (lseek (kfd, N_TXTOFF(kexec), SEEK_SET) == -1)
  14209. +    if (lseek (kfd, text_offset, SEEK_SET) == -1)
  14210.      {
  14211.      fprintf (stderr, "Failed to seek to text\n");
  14212.      Mfree ((void *)memptr);
  14213. @@ -446,12 +555,8 @@
  14214.      Mfree ((void *)memptr);
  14215.      boot_exit (EXIT_FAILURE);
  14216.      }
  14217. -    if (lseek (kfd, N_DATOFF(kexec), SEEK_SET) == -1)
  14218. -    {
  14219. -    fprintf (stderr, "Failed to seek to data\n");
  14220. -    Mfree ((void *)memptr);
  14221. -    boot_exit (EXIT_FAILURE);
  14222. -    }
  14223. +
  14224. +    /* data follows immediately after text */
  14225.      if (read (kfd, memptr + kexec.a_text, kexec.a_data) != kexec.a_data)
  14226.      {
  14227.      fprintf (stderr, "Failed to read data\n");
  14228. @@ -460,8 +565,9 @@
  14229.      }
  14230.      close (kfd);
  14231.  
  14232. -    /* copy the boot_info struct to the kernel image */
  14233. -    memcpy ((void *)(memptr + kbi_offset), &bi, sizeof(bi));
  14234. +    /* copy the boot_info struct to the end of the kernel image */
  14235. +    memcpy ((void *)(memptr + kexec.a_text + kexec.a_data + kexec.a_bss),
  14236. +        &bi, sizeof(bi));
  14237.  
  14238.      /* read the ramdisk image */
  14239.      if (rfd != -1)
  14240. @@ -472,7 +578,7 @@
  14241.          Mfree ((void *)memptr);
  14242.          boot_exit (EXIT_FAILURE);
  14243.      }
  14244. -    if (read (rfd, memptr + kexec.a_text + kexec.a_data + kexec.a_bss,
  14245. +    if (read (rfd, memptr + kexec.a_text + kexec.a_data + kexec.a_bss + sizeof (bi),
  14246.            rd_size) != rd_size)
  14247.      {
  14248.          fprintf (stderr, "Failed to read ramdisk file\n");
  14249. @@ -491,13 +597,13 @@
  14250.              bi.ramdisk_size);
  14251.  
  14252.      printf ("\nKernel text at %#lx, code size %d\n",
  14253. -        start_mem + N_TXTADDR(kexec), kexec.a_text);
  14254. +        start_mem, kexec.a_text);
  14255.      printf ("Kernel data at %#lx, data size %d\n",
  14256. -        start_mem + N_DATADDR(kexec), kexec.a_data );
  14257. +        start_mem + kexec.a_text, kexec.a_data );
  14258.      printf ("Kernel bss  at %#lx, bss  size %d\n",
  14259. -        start_mem + N_BSSADDR(kexec), kexec.a_bss );
  14260. -    printf ("\nKernel boot_info is at %#lx physical, %#lx virtual\n",
  14261. -        start_mem + kbi_offset, kexec.a_entry + kbi_offset);
  14262. +        start_mem + kexec.a_text + kexec.a_data, kexec.a_bss );
  14263. +    printf ("\nboot_info is at %#lx\n",
  14264. +        start_mem + kexec.a_text + kexec.a_data + kexec.a_bss);
  14265.      printf ("\nKernel entry is %#x\n", kexec.a_entry );
  14266.      printf ("ramdisk dest top is %#lx\n", start_mem + mem_size);
  14267.      printf ("ramdisk lower limit is %#lx\n",
  14268. @@ -505,6 +611,11 @@
  14269.      printf ("ramdisk src top is %#lx\n",
  14270.          (u_long)(memptr + kexec.a_text + kexec.a_data + kexec.a_bss) +
  14271.          rd_size);
  14272. +#if 0
  14273. +    printf ("mover code resides from %#lx to %#lx\n",
  14274. +            (unsigned long)mover_addr,
  14275. +            (unsigned long)mover_addr + mover_size - 1 );
  14276. +#endif
  14277.  
  14278.      printf ("Type a key to continue the Linux boot...");
  14279.      fflush (stdout);
  14280. @@ -524,11 +635,20 @@
  14281.      /* ..and any MMU translation */
  14282.      disable_mmu();
  14283.  
  14284. -    /* copy mover code to a safe place */
  14285. -    memcpy((void*)0x400, ©all, ©allend - ©all);
  14286. +    /* copy mover code to a safe place if needed */
  14287. +#if 0
  14288. +    if (mover_addr != ©all)
  14289. +        memcpy( mover_addr, ©all, mover_size );
  14290. +#else
  14291. +    memcpy ((void *) 0x400, ©all, ©allend - ©all);
  14292. +#endif
  14293.  
  14294.      /* setup stack */
  14295. -    change_stack((void*)PAGE_SIZE);
  14296. +#if 0
  14297. +    change_stack( start_mem ? PAGE_SIZE : (void*)start_mem+mem_size-rd_size-8);
  14298. +#else
  14299. +    change_stack ((void *) PAGE_SIZE);
  14300. +#endif
  14301.  
  14302.      /*
  14303.       * On the Atari you can have two situations:
  14304. @@ -547,12 +667,87 @@
  14305.       * This is more than enough for the miniscule mover routine (16 bytes).
  14306.       */
  14307.      
  14308. +#if 0
  14309. +    /* New copy scheme for new memory layout: The first 8 kernel bytes
  14310. +     * are nop's that needn't be copied. This avoids accessing the ROM
  14311. +     * bytes at the start of ST-Ram if the kernel will go there. The
  14312. +     * first arguement is the kernel start address, too.
  14313. +     * The mover code was copied to a place disjunct from any of the
  14314. +     * destination areas. 
  14315. +     */
  14316. +    
  14317. +    jump_to_mover((char *) start_mem + 8, memptr + 8,
  14318. +          (char *) start_mem + mem_size, memptr + memreq,
  14319. +          kexec.a_text + kexec.a_data + kexec.a_bss - 8,
  14320. +          rd_size,
  14321. +          mover_addr );
  14322. +#else
  14323.      jump_to_mover((char *) start_mem, memptr,
  14324.            (char *) start_mem + mem_size, memptr + memreq,
  14325. -          kexec.a_text + kexec.a_data + kexec.a_bss,
  14326. +          kexec.a_text + kexec.a_data + kexec.a_bss + sizeof (bi),
  14327.            rd_size,
  14328. -          (void*)0x400);
  14329. +          (void *) 0x400);
  14330. +#endif
  14331.      for (;;);
  14332.      /* NOTREACHED */
  14333.  }
  14334. +
  14335. +
  14336. +
  14337. +#define    MAXARGS        30
  14338. +
  14339. +static void get_default_args( int *argc, char ***argv )
  14340. +
  14341. +{    FILE        *f;
  14342. +    static char    *nargv[MAXARGS];
  14343. +    char        arg[256], *p;
  14344. +    int            c, quote, state;
  14345. +
  14346. +    if (!(f = fopen( "bootargs", "r" )))
  14347. +        return;
  14348. +    
  14349. +    *argc = 1;
  14350. +    if (***argv)
  14351. +      nargv[0] = **argv;
  14352. +    else
  14353. +      nargv[0] = "bootstrap";
  14354. +    *argv = nargv;
  14355. +
  14356. +    quote = state = 0;
  14357. +    p = arg;
  14358. +    while( (c = fgetc(f)) != EOF ) {        
  14359. +
  14360. +        if (state == 0) {
  14361. +            /* outside args, skip whitespace */
  14362. +            if (!isspace(c)) {
  14363. +                state = 1;
  14364. +                p = arg;
  14365. +            }
  14366. +        }
  14367. +        
  14368. +        if (state) {
  14369. +            /* inside an arg: copy it into 'arg', obeying quoting */
  14370. +            if (!quote && (c == '\'' || c == '"'))
  14371. +                quote = c;
  14372. +            else if (quote && c == quote)
  14373. +                quote = 0;
  14374. +            else if (!quote && isspace(c)) {
  14375. +                /* end of this arg */
  14376. +                *p = 0;
  14377. +                nargv[(*argc)++] = strdup(arg);
  14378. +                state = 0;
  14379. +            }
  14380. +            else
  14381. +                *p++ = c;
  14382. +        }
  14383. +    }
  14384. +    if (state) {
  14385. +        /* last arg finished by EOF! */
  14386. +        *p = 0;
  14387. +        nargv[(*argc)++] = strdup(arg);
  14388. +    }
  14389. +    fclose( f );
  14390. +    
  14391. +    nargv[*argc] = 0;
  14392. +}    
  14393.  
  14394.